diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..360e483 --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +cache/cache_*.php +include/user/* +img/avatars/*.png +img/avatars/*.jpg +img/avatars/*.gif +config.php diff --git a/admin_bans.php b/admin_bans.php new file mode 100644 index 0000000..904f16f --- /dev/null +++ b/admin_bans.php @@ -0,0 +1,537 @@ +query('SELECT group_id, username, email FROM '.$db->prefix.'users WHERE id='.$user_id) or error('Unable to fetch user info', __FILE__, __LINE__, $db->error()); + if ($db->num_rows($result)) + list($group_id, $ban_user, $ban_email) = $db->fetch_row($result); + else + message($lang_admin_bans['No user ID message']); + } + else // Otherwise the username is in POST + { + $ban_user = pun_trim($_POST['new_ban_user']); + + if ($ban_user != '') + { + $result = $db->query('SELECT id, group_id, username, email FROM '.$db->prefix.'users WHERE username=\''.$db->escape($ban_user).'\' AND id>1') or error('Unable to fetch user info', __FILE__, __LINE__, $db->error()); + if ($db->num_rows($result)) + list($user_id, $group_id, $ban_user, $ban_email) = $db->fetch_row($result); + else + message($lang_admin_bans['No user message']); + } + } + + // Make sure we're not banning an admin + if (isset($group_id) && $group_id == PUN_ADMIN) + message(sprintf($lang_admin_bans['User is admin message'], pun_htmlspecialchars($ban_user))); + + // If we have a $user_id, we can try to find the last known IP of that user + if (isset($user_id)) + { + $result = $db->query('SELECT poster_ip FROM '.$db->prefix.'posts WHERE poster_id='.$user_id.' ORDER BY posted DESC LIMIT 1') or error('Unable to fetch post info', __FILE__, __LINE__, $db->error()); + $ban_ip = ($db->num_rows($result)) ? $db->result($result) : ''; + } + + $mode = 'add'; + } + else // We are editing a ban + { + $ban_id = intval($_GET['edit_ban']); + if ($ban_id < 1) + message($lang_common['Bad request']); + + $result = $db->query('SELECT username, ip, email, message, expire FROM '.$db->prefix.'bans WHERE id='.$ban_id) or error('Unable to fetch ban info', __FILE__, __LINE__, $db->error()); + if ($db->num_rows($result)) + list($ban_user, $ban_ip, $ban_email, $ban_message, $ban_expire) = $db->fetch_row($result); + else + message($lang_common['Bad request']); + + $diff = ($pun_user['timezone'] + $pun_user['dst']) * 3600; + $ban_expire = ($ban_expire != '') ? gmdate('Y-m-d', $ban_expire + $diff) : ''; + + $mode = 'edit'; + } + + $page_title = array(pun_htmlspecialchars($pun_config['o_board_title']), $lang_admin_common['Admin'], $lang_admin_common['Bans']); + $focus_element = array('bans2', 'ban_user'); + define('PUN_ACTIVE_PAGE', 'admin'); + require PUN_ROOT.'header.php'; + + generate_admin_menu('bans'); + +?> +
+

+
+
+
+ + +
+ +
+ + + + + + + + + + + + + +
+ + +
+ + '.$lang_admin_common['here'].'') ?> +
+ + +
+

+
+
+
+
+
+ +
+ + + + + + + + + +
+ + +
+ + +
+
+
+
+

+
+
+
+
+ + 7 || (!empty($octets[$c]) && !ctype_xdigit($octets[$c])) || intval($octets[$c], 16) > 65535) + message($lang_admin_bans['Invalid IP message']); + } + + $cur_address = implode(':', $octets); + $addresses[$i] = $cur_address; + } + else + { + $octets = explode('.', $addresses[$i]); + + for ($c = 0; $c < count($octets); ++$c) + { + $octets[$c] = (strlen($octets[$c]) > 1) ? ltrim($octets[$c], "0") : $octets[$c]; + + if ($c > 3 || preg_match('/[^0-9]/', $octets[$c]) || intval($octets[$c]) > 255) + message($lang_admin_bans['Invalid IP message']); + } + + $cur_address = implode('.', $octets); + $addresses[$i] = $cur_address; + } + } + + $ban_ip = implode(' ', $addresses); + } + + require PUN_ROOT.'include/email.php'; + if ($ban_email != '' && !is_valid_email($ban_email)) + { + if (!preg_match('/^[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,4})$/', $ban_email)) + message($lang_admin_bans['Invalid e-mail message']); + } + + if ($ban_expire != '' && $ban_expire != 'Never') + { + $ban_expire = strtotime($ban_expire.' GMT'); + + if ($ban_expire == -1 || !$ban_expire) + message($lang_admin_bans['Invalid date message'].' '.$lang_admin_bans['Invalid date reasons']); + + $diff = ($pun_user['timezone'] + $pun_user['dst']) * 3600; + $ban_expire -= $diff; + + if ($ban_expire <= time()) + message($lang_admin_bans['Invalid date message'].' '.$lang_admin_bans['Invalid date reasons']); + } + else + $ban_expire = 'NULL'; + + $ban_user = ($ban_user != '') ? '\''.$db->escape($ban_user).'\'' : 'NULL'; + $ban_ip = ($ban_ip != '') ? '\''.$db->escape($ban_ip).'\'' : 'NULL'; + $ban_email = ($ban_email != '') ? '\''.$db->escape($ban_email).'\'' : 'NULL'; + $ban_message = ($ban_message != '') ? '\''.$db->escape($ban_message).'\'' : 'NULL'; + + if ($_POST['mode'] == 'add') + $db->query('INSERT INTO '.$db->prefix.'bans (username, ip, email, message, expire, ban_creator) VALUES('.$ban_user.', '.$ban_ip.', '.$ban_email.', '.$ban_message.', '.$ban_expire.', '.$pun_user['id'].')') or error('Unable to add ban', __FILE__, __LINE__, $db->error()); + else + $db->query('UPDATE '.$db->prefix.'bans SET username='.$ban_user.', ip='.$ban_ip.', email='.$ban_email.', message='.$ban_message.', expire='.$ban_expire.' WHERE id='.intval($_POST['ban_id'])) or error('Unable to update ban', __FILE__, __LINE__, $db->error()); + + // Regenerate the bans cache + if (!defined('FORUM_CACHE_FUNCTIONS_LOADED')) + require PUN_ROOT.'include/cache.php'; + + generate_bans_cache(); + + if ($_POST['mode'] == 'edit') + redirect('admin_bans.php', $lang_admin_bans['Ban edited redirect']); + else + redirect('admin_bans.php', $lang_admin_bans['Ban added redirect']); +} + +// Remove a ban +else if (isset($_GET['del_ban'])) +{ + confirm_referrer('admin_bans.php'); + + $ban_id = intval($_GET['del_ban']); + if ($ban_id < 1) + message($lang_common['Bad request']); + + $db->query('DELETE FROM '.$db->prefix.'bans WHERE id='.$ban_id) or error('Unable to delete ban', __FILE__, __LINE__, $db->error()); + + // Regenerate the bans cache + if (!defined('FORUM_CACHE_FUNCTIONS_LOADED')) + require PUN_ROOT.'include/cache.php'; + + generate_bans_cache(); + + redirect('admin_bans.php', $lang_admin_bans['Ban removed redirect']); +} + +// Find bans +else if (isset($_GET['find_ban'])) +{ + $form = isset($_GET['form']) ? $_GET['form'] : array(); + + // trim() all elements in $form + $form = array_map('pun_trim', $form); + $conditions = $query_str = array(); + + $expire_after = isset($_GET['expire_after']) ? trim($_GET['expire_after']) : ''; + $expire_before = isset($_GET['expire_before']) ? trim($_GET['expire_before']) : ''; + $order_by = isset($_GET['order_by']) && in_array($_GET['order_by'], array('username', 'ip', 'email', 'expire')) ? $_GET['order_by'] : 'username'; + $direction = isset($_GET['direction']) && $_GET['direction'] == 'DESC' ? 'DESC' : 'ASC'; + + $query_str[] = 'order_by='.$order_by; + $query_str[] = 'direction='.$direction; + + // Try to convert date/time to timestamps + if ($expire_after != '') + { + $query_str[] = 'expire_after='.$expire_after; + + $expire_after = strtotime($expire_after); + if ($expire_after === false || $expire_after == -1) + message($lang_admin_bans['Invalid date message']); + + $conditions[] = 'expire>'.$expire_after; + } + if ($expire_before != '') + { + $query_str[] = 'expire_before='.$expire_before; + + $expire_before = strtotime($expire_before); + if ($expire_before === false || $expire_before == -1) + message($lang_admin_bans['Invalid date message']); + + $conditions[] = 'expire<'.$expire_before; + } + + $like_command = ($db_type == 'pgsql') ? 'ILIKE' : 'LIKE'; + foreach ($form as $key => $input) + { + if ($input != '' && in_array($key, array('username', 'ip', 'email', 'message'))) + { + $conditions[] = 'b.'.$db->escape($key).' '.$like_command.' \''.$db->escape(str_replace('*', '%', $input)).'\''; + $query_str[] = 'form%5B'.$key.'%5D='.urlencode($input); + } + } + + // Fetch ban count + $result = $db->query('SELECT COUNT(id) FROM '.$db->prefix.'bans as b WHERE b.id>0'.(!empty($conditions) ? ' AND '.implode(' AND ', $conditions) : '')) or error('Unable to fetch ban list', __FILE__, __LINE__, $db->error()); + $num_bans = $db->result($result); + + // Determine the ban offset (based on $_GET['p']) + $num_pages = ceil($num_bans / 50); + + $p = (!isset($_GET['p']) || $_GET['p'] <= 1 || $_GET['p'] > $num_pages) ? 1 : intval($_GET['p']); + $start_from = 50 * ($p - 1); + + // Generate paging links + $paging_links = ''.$lang_common['Pages'].' '.paginate($num_pages, $p, 'admin_bans.php?find_ban=&'.implode('&', $query_str)); + + $page_title = array(pun_htmlspecialchars($pun_config['o_board_title']), $lang_admin_common['Admin'], $lang_admin_common['Bans'], $lang_admin_bans['Results head']); + define('PUN_ACTIVE_PAGE', 'admin'); + require PUN_ROOT.'header.php'; + +?> +
+
+ +
+ +
+
+
+
+ + +
+

+
+
+ + + + + + + + + + + + + +query('SELECT b.id, b.username, b.ip, b.email, b.message, b.expire, b.ban_creator, u.username AS ban_creator_username FROM '.$db->prefix.'bans AS b LEFT JOIN '.$db->prefix.'users AS u ON b.ban_creator=u.id WHERE b.id>0'.(!empty($conditions) ? ' AND '.implode(' AND ', $conditions) : '').' ORDER BY '.$db->escape($order_by).' '.$db->escape($direction).' LIMIT '.$start_from.', 50') or error('Unable to fetch ban list', __FILE__, __LINE__, $db->error()); + if ($db->num_rows($result)) + { + while ($ban_data = $db->fetch_assoc($result)) + { + + $actions = ''.$lang_admin_common['Edit'].' | '.$lang_admin_common['Remove'].''; + $expire = format_time($ban_data['expire'], true); + +?> + + + + + + + + + +'."\n"; + +?> + +
'.pun_htmlspecialchars($ban_data['ban_creator_username']).'' : $lang_admin_bans['Unknown'] ?>
'.$lang_admin_bans['No match'].'
+
+
+
+ +
+
+
+ +
+ +
+
+
+ +
+

+
+
+
+
+ +
+ + + + + +
+ + +
+
+
+
+
+
+ +

+
+
+

+
+
+ +
+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+     +
+
+
+
+

+
+
+
+
+ +query('INSERT INTO '.$db->prefix.'categories (cat_name) VALUES(\''.$db->escape($new_cat_name).'\')') or error('Unable to create category', __FILE__, __LINE__, $db->error()); + + redirect('admin_categories.php', $lang_admin_categories['Category added redirect']); +} + +// Delete a category +else if (isset($_POST['del_cat']) || isset($_POST['del_cat_comply'])) +{ + confirm_referrer('admin_categories.php'); + + $cat_to_delete = intval($_POST['cat_to_delete']); + if ($cat_to_delete < 1) + message($lang_common['Bad request']); + + if (isset($_POST['del_cat_comply'])) // Delete a category with all forums and posts + { + @set_time_limit(0); + + $result = $db->query('SELECT id FROM '.$db->prefix.'forums WHERE cat_id='.$cat_to_delete) or error('Unable to fetch forum list', __FILE__, __LINE__, $db->error()); + $num_forums = $db->num_rows($result); + + for ($i = 0; $i < $num_forums; ++$i) + { + $cur_forum = $db->result($result, $i); + + // Prune all posts and topics + prune($cur_forum, 1, -1); + + // Delete the forum + $db->query('DELETE FROM '.$db->prefix.'forums WHERE id='.$cur_forum) or error('Unable to delete forum', __FILE__, __LINE__, $db->error()); + } + + // Locate any "orphaned redirect topics" and delete them + $result = $db->query('SELECT t1.id FROM '.$db->prefix.'topics AS t1 LEFT JOIN '.$db->prefix.'topics AS t2 ON t1.moved_to=t2.id WHERE t2.id IS NULL AND t1.moved_to IS NOT NULL') or error('Unable to fetch redirect topics', __FILE__, __LINE__, $db->error()); + $num_orphans = $db->num_rows($result); + + if ($num_orphans) + { + for ($i = 0; $i < $num_orphans; ++$i) + $orphans[] = $db->result($result, $i); + + $db->query('DELETE FROM '.$db->prefix.'topics WHERE id IN('.implode(',', $orphans).')') or error('Unable to delete redirect topics', __FILE__, __LINE__, $db->error()); + } + + // Delete the category + $db->query('DELETE FROM '.$db->prefix.'categories WHERE id='.$cat_to_delete) or error('Unable to delete category', __FILE__, __LINE__, $db->error()); + + // Regenerate the quick jump cache + if (!defined('FORUM_CACHE_FUNCTIONS_LOADED')) + require PUN_ROOT.'include/cache.php'; + + generate_quickjump_cache(); + + redirect('admin_categories.php', $lang_admin_categories['Category deleted redirect']); + } + else // If the user hasn't comfirmed the delete + { + $result = $db->query('SELECT cat_name FROM '.$db->prefix.'categories WHERE id='.$cat_to_delete) or error('Unable to fetch category info', __FILE__, __LINE__, $db->error()); + $cat_name = $db->result($result); + + $page_title = array(pun_htmlspecialchars($pun_config['o_board_title']), $lang_admin_common['Admin'], $lang_admin_common['Categories']); + define('PUN_ACTIVE_PAGE', 'admin'); + require PUN_ROOT.'header.php'; + + generate_admin_menu('categories'); + +?> +
+

+
+
+
+ +
+ +
+

+

+
+
+
+

+
+
+
+
+ +query('SELECT id, disp_position FROM '.$db->prefix.'categories ORDER BY disp_position') or error('Unable to fetch category list', __FILE__, __LINE__, $db->error()); + $num_cats = $db->num_rows($result); + + for ($i = 0; $i < $num_cats; ++$i) + { + if ($cat_name[$i] == '') + message($lang_admin_categories['Must enter name message']); + + if ($cat_order[$i] == '' || preg_match('/[^0-9]/', $cat_order[$i])) + message($lang_admin_categories['Must enter integer message']); + + list($cat_id, $position) = $db->fetch_row($result); + + $db->query('UPDATE '.$db->prefix.'categories SET cat_name=\''.$db->escape($cat_name[$i]).'\', disp_position='.$cat_order[$i].' WHERE id='.$cat_id) or error('Unable to update category', __FILE__, __LINE__, $db->error()); + } + + // Regenerate the quick jump cache + if (!defined('FORUM_CACHE_FUNCTIONS_LOADED')) + require PUN_ROOT.'include/cache.php'; + + generate_quickjump_cache(); + + redirect('admin_categories.php', $lang_admin_categories['Categories updated redirect']); +} + +// Generate an array with all categories +$result = $db->query('SELECT id, cat_name, disp_position FROM '.$db->prefix.'categories ORDER BY disp_position') or error('Unable to fetch category list', __FILE__, __LINE__, $db->error()); +$num_cats = $db->num_rows($result); + +for ($i = 0; $i < $num_cats; ++$i) + $cat_list[] = $db->fetch_row($result); + +$page_title = array(pun_htmlspecialchars($pun_config['o_board_title']), $lang_admin_common['Admin'], $lang_admin_common['Categories']); +define('PUN_ACTIVE_PAGE', 'admin'); +require PUN_ROOT.'header.php'; + +generate_admin_menu('categories'); + +?> +
+

+
+
+
+
+ +
+ + + + + +
+ + '.$lang_admin_common['Forums'].'') ?> +
+
+
+
+
+
+ +

+
+
+
+
+ +
+ + + + + +
+ + +
+
+
+
+
+
+ + +

+
+
+
+
+ +
+ + + + + + + + + $category) + { + +?> + + + + + + +
+
+
+
+
+
+
+
+
+ +query('INSERT INTO '.$db->prefix.'censoring (search_for, replace_with) VALUES (\''.$db->escape($search_for).'\', \''.$db->escape($replace_with).'\')') or error('Unable to add censor word', __FILE__, __LINE__, $db->error()); + + redirect('admin_censoring.php', $lang_admin_censoring['Word added redirect']); +} + +// Update a censor word +else if (isset($_POST['update'])) +{ + confirm_referrer('admin_censoring.php'); + + $id = intval(key($_POST['update'])); + + $search_for = pun_trim($_POST['search_for'][$id]); + $replace_with = pun_trim($_POST['replace_with'][$id]); + + if ($search_for == '' || $replace_with == '') + message($lang_admin_censoring['Must search both message']); + + $db->query('UPDATE '.$db->prefix.'censoring SET search_for=\''.$db->escape($search_for).'\', replace_with=\''.$db->escape($replace_with).'\' WHERE id='.$id) or error('Unable to update censor word', __FILE__, __LINE__, $db->error()); + + redirect('admin_censoring.php', $lang_admin_censoring['Word updated redirect']); +} + +// Remove a censor word +else if (isset($_POST['remove'])) +{ + confirm_referrer('admin_censoring.php'); + + $id = intval(key($_POST['remove'])); + + $db->query('DELETE FROM '.$db->prefix.'censoring WHERE id='.$id) or error('Unable to delete censor word', __FILE__, __LINE__, $db->error()); + + redirect('admin_censoring.php', $lang_admin_censoring['Word removed redirect']); +} + +$page_title = array(pun_htmlspecialchars($pun_config['o_board_title']), $lang_admin_common['Admin'], $lang_admin_common['Censoring']); +$focus_element = array('censoring', 'new_search_for'); +define('PUN_ACTIVE_PAGE', 'admin'); +require PUN_ROOT.'header.php'; + +generate_admin_menu('censoring'); + +?> +
+

+
+
+
+
+ +
+

'.$lang_admin_common['Options'].'') ?>

+ + + + + + + + + + + + + + + +
+
+
+
+
+
+ +
+query('SELECT id, search_for, replace_with FROM '.$db->prefix.'censoring ORDER BY id') or error('Unable to fetch censor word list', __FILE__, __LINE__, $db->error()); +if ($db->num_rows($result)) +{ + +?> + + + + + + + + + +fetch_assoc($result)) + echo "\t\t\t\t\t\t\t\t".''."\n"; + +?> + +
 
+'.$lang_admin_censoring['No words in list'].'

'."\n"; + +?> +
+
+
+
+
+
+
+ +query('INSERT INTO '.$db->prefix.'forums (cat_id) VALUES('.$add_to_cat.')') or error('Unable to create forum', __FILE__, __LINE__, $db->error()); + + // Regenerate the quick jump cache + if (!defined('FORUM_CACHE_FUNCTIONS_LOADED')) + require PUN_ROOT.'include/cache.php'; + + generate_quickjump_cache(); + + redirect('admin_forums.php', $lang_admin_forums['Forum added redirect']); +} + +// Delete a forum +else if (isset($_GET['del_forum'])) +{ + confirm_referrer('admin_forums.php'); + + $forum_id = intval($_GET['del_forum']); + if ($forum_id < 1) + message($lang_common['Bad request']); + + if (isset($_POST['del_forum_comply'])) // Delete a forum with all posts + { + @set_time_limit(0); + + // Prune all posts and topics + prune($forum_id, 1, -1); + + // Locate any "orphaned redirect topics" and delete them + $result = $db->query('SELECT t1.id FROM '.$db->prefix.'topics AS t1 LEFT JOIN '.$db->prefix.'topics AS t2 ON t1.moved_to=t2.id WHERE t2.id IS NULL AND t1.moved_to IS NOT NULL') or error('Unable to fetch redirect topics', __FILE__, __LINE__, $db->error()); + $num_orphans = $db->num_rows($result); + + if ($num_orphans) + { + for ($i = 0; $i < $num_orphans; ++$i) + $orphans[] = $db->result($result, $i); + + $db->query('DELETE FROM '.$db->prefix.'topics WHERE id IN('.implode(',', $orphans).')') or error('Unable to delete redirect topics', __FILE__, __LINE__, $db->error()); + } + + // Delete the forum and any forum specific group permissions + $db->query('DELETE FROM '.$db->prefix.'forums WHERE id='.$forum_id) or error('Unable to delete forum', __FILE__, __LINE__, $db->error()); + $db->query('DELETE FROM '.$db->prefix.'forum_perms WHERE forum_id='.$forum_id) or error('Unable to delete group forum permissions', __FILE__, __LINE__, $db->error()); + + // Regenerate the quick jump cache + if (!defined('FORUM_CACHE_FUNCTIONS_LOADED')) + require PUN_ROOT.'include/cache.php'; + + generate_quickjump_cache(); + + redirect('admin_forums.php', $lang_admin_forums['Forum deleted redirect']); + } + else // If the user hasn't confirmed the delete + { + $result = $db->query('SELECT forum_name FROM '.$db->prefix.'forums WHERE id='.$forum_id) or error('Unable to fetch forum info', __FILE__, __LINE__, $db->error()); + $forum_name = pun_htmlspecialchars($db->result($result)); + + $page_title = array(pun_htmlspecialchars($pun_config['o_board_title']), $lang_admin_common['Admin'], $lang_admin_common['Forums']); + define('PUN_ACTIVE_PAGE', 'admin'); + require PUN_ROOT.'header.php'; + + generate_admin_menu('forums'); + +?> +
+

+
+
+
+
+ +
+

+

+
+
+
+

+
+
+
+
+ + $disp_position) + { + $disp_position = trim($disp_position); + if ($disp_position == '' || preg_match('/[^0-9]/', $disp_position)) + message($lang_admin_forums['Must be integer message']); + + $db->query('UPDATE '.$db->prefix.'forums SET disp_position='.$disp_position.' WHERE id='.intval($forum_id)) or error('Unable to update forum', __FILE__, __LINE__, $db->error()); + } + + // Regenerate the quick jump cache + if (!defined('FORUM_CACHE_FUNCTIONS_LOADED')) + require PUN_ROOT.'include/cache.php'; + + generate_quickjump_cache(); + + redirect('admin_forums.php', $lang_admin_forums['Forums updated redirect']); +} + +else if (isset($_GET['edit_forum'])) +{ + $forum_id = intval($_GET['edit_forum']); + if ($forum_id < 1) + message($lang_common['Bad request']); + + // Update group permissions for $forum_id + if (isset($_POST['save'])) + { + confirm_referrer('admin_forums.php'); + + // Start with the forum details + $forum_name = pun_trim($_POST['forum_name']); + $forum_desc = pun_linebreaks(pun_trim($_POST['forum_desc'])); + $cat_id = intval($_POST['cat_id']); + $sort_by = intval($_POST['sort_by']); + $redirect_url = isset($_POST['redirect_url']) ? trim($_POST['redirect_url']) : null; + + if ($forum_name == '') + message($lang_admin_forums['Must enter name message']); + + if ($cat_id < 1) + message($lang_common['Bad request']); + + $forum_desc = ($forum_desc != '') ? '\''.$db->escape($forum_desc).'\'' : 'NULL'; + $redirect_url = ($redirect_url != '') ? '\''.$db->escape($redirect_url).'\'' : 'NULL'; + + $db->query('UPDATE '.$db->prefix.'forums SET forum_name=\''.$db->escape($forum_name).'\', forum_desc='.$forum_desc.', redirect_url='.$redirect_url.', sort_by='.$sort_by.', cat_id='.$cat_id.' WHERE id='.$forum_id) or error('Unable to update forum', __FILE__, __LINE__, $db->error()); + + // Now let's deal with the permissions + if (isset($_POST['read_forum_old'])) + { + $result = $db->query('SELECT g_id, g_read_board, g_post_replies, g_post_topics FROM '.$db->prefix.'groups WHERE g_id!='.PUN_ADMIN) or error('Unable to fetch user group list', __FILE__, __LINE__, $db->error()); + while ($cur_group = $db->fetch_assoc($result)) + { + $read_forum_new = ($cur_group['g_read_board'] == '1') ? isset($_POST['read_forum_new'][$cur_group['g_id']]) ? '1' : '0' : intval($_POST['read_forum_old'][$cur_group['g_id']]); + $post_replies_new = isset($_POST['post_replies_new'][$cur_group['g_id']]) ? '1' : '0'; + $post_topics_new = isset($_POST['post_topics_new'][$cur_group['g_id']]) ? '1' : '0'; + + // Check if the new settings differ from the old + if ($read_forum_new != $_POST['read_forum_old'][$cur_group['g_id']] || $post_replies_new != $_POST['post_replies_old'][$cur_group['g_id']] || $post_topics_new != $_POST['post_topics_old'][$cur_group['g_id']]) + { + // If the new settings are identical to the default settings for this group, delete it's row in forum_perms + if ($read_forum_new == '1' && $post_replies_new == $cur_group['g_post_replies'] && $post_topics_new == $cur_group['g_post_topics']) + $db->query('DELETE FROM '.$db->prefix.'forum_perms WHERE group_id='.$cur_group['g_id'].' AND forum_id='.$forum_id) or error('Unable to delete group forum permissions', __FILE__, __LINE__, $db->error()); + else + { + // Run an UPDATE and see if it affected a row, if not, INSERT + $db->query('UPDATE '.$db->prefix.'forum_perms SET read_forum='.$read_forum_new.', post_replies='.$post_replies_new.', post_topics='.$post_topics_new.' WHERE group_id='.$cur_group['g_id'].' AND forum_id='.$forum_id) or error('Unable to insert group forum permissions', __FILE__, __LINE__, $db->error()); + if (!$db->affected_rows()) + $db->query('INSERT INTO '.$db->prefix.'forum_perms (group_id, forum_id, read_forum, post_replies, post_topics) VALUES('.$cur_group['g_id'].', '.$forum_id.', '.$read_forum_new.', '.$post_replies_new.', '.$post_topics_new.')') or error('Unable to insert group forum permissions', __FILE__, __LINE__, $db->error()); + } + } + } + } + + // Regenerate the quick jump cache + if (!defined('FORUM_CACHE_FUNCTIONS_LOADED')) + require PUN_ROOT.'include/cache.php'; + + generate_quickjump_cache(); + + redirect('admin_forums.php', $lang_admin_forums['Forum updated redirect']); + } + else if (isset($_POST['revert_perms'])) + { + confirm_referrer('admin_forums.php'); + + $db->query('DELETE FROM '.$db->prefix.'forum_perms WHERE forum_id='.$forum_id) or error('Unable to delete group forum permissions', __FILE__, __LINE__, $db->error()); + + // Regenerate the quick jump cache + if (!defined('FORUM_CACHE_FUNCTIONS_LOADED')) + require PUN_ROOT.'include/cache.php'; + + generate_quickjump_cache(); + + redirect('admin_forums.php?edit_forum='.$forum_id, $lang_admin_forums['Perms reverted redirect']); + } + + // Fetch forum info + $result = $db->query('SELECT id, forum_name, forum_desc, redirect_url, num_topics, sort_by, cat_id FROM '.$db->prefix.'forums WHERE id='.$forum_id) or error('Unable to fetch forum info', __FILE__, __LINE__, $db->error()); + if (!$db->num_rows($result)) + message($lang_common['Bad request']); + + $cur_forum = $db->fetch_assoc($result); + + $page_title = array(pun_htmlspecialchars($pun_config['o_board_title']), $lang_admin_common['Admin'], $lang_admin_common['Forums']); + define('PUN_ACTIVE_PAGE', 'admin'); + require PUN_ROOT.'header.php'; + + generate_admin_menu('forums'); + +?> +
+

+
+
+

+
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
'; ?>
+
+
+
+
+
+ +
+

'.$lang_admin_common['User groups'].'') ?>

+ + + + + + + + + + +query('SELECT g.g_id, g.g_title, g.g_read_board, g.g_post_replies, g.g_post_topics, fp.read_forum, fp.post_replies, fp.post_topics FROM '.$db->prefix.'groups AS g LEFT JOIN '.$db->prefix.'forum_perms AS fp ON (g.g_id=fp.group_id AND fp.forum_id='.$forum_id.') WHERE g.g_id!='.PUN_ADMIN.' ORDER BY g.g_id') or error('Unable to fetch group forum permission list', __FILE__, __LINE__, $db->error()); + + while ($cur_perm = $db->fetch_assoc($result)) + { + $read_forum = ($cur_perm['read_forum'] != '0') ? true : false; + $post_replies = (($cur_perm['g_post_replies'] == '0' && $cur_perm['post_replies'] == '1') || ($cur_perm['g_post_replies'] == '1' && $cur_perm['post_replies'] != '0')) ? true : false; + $post_topics = (($cur_perm['g_post_topics'] == '0' && $cur_perm['post_topics'] == '1') || ($cur_perm['g_post_topics'] == '1' && $cur_perm['post_topics'] != '0')) ? true : false; + + // Determine if the current settings differ from the default or not + $read_forum_def = ($cur_perm['read_forum'] == '0') ? false : true; + $post_replies_def = (($post_replies && $cur_perm['g_post_replies'] == '0') || (!$post_replies && ($cur_perm['g_post_replies'] == '' || $cur_perm['g_post_replies'] == '1'))) ? false : true; + $post_topics_def = (($post_topics && $cur_perm['g_post_topics'] == '0') || (!$post_topics && ($cur_perm['g_post_topics'] == '' || $cur_perm['g_post_topics'] == '1'))) ? false : true; + +?> + + + > + + /> + + > + + /> + + > + + /> + + + + +
 
+
+
+
+
+

+
+
+
+
+ + + +
+

+
+
+
+
+ +
+ + + + + +
+ + +
+
+
+
+
+
+query('SELECT c.id AS cid, c.cat_name, f.id AS fid, f.forum_name, f.disp_position FROM '.$db->prefix.'categories AS c INNER JOIN '.$db->prefix.'forums AS f ON c.id=f.cat_id ORDER BY c.disp_position, c.id, f.disp_position') or error('Unable to fetch category/forum list', __FILE__, __LINE__, $db->error()); + +if ($db->num_rows($result) > 0) +{ + +?> +

+
+
+

+fetch_assoc($result)) +{ + if ($cur_forum['cid'] != $cur_category) // A new category since last iteration? + { + if ($cur_category != 0) + echo "\t\t\t\t\t\t\t".''."\n\t\t\t\t\t\t\t".''."\n\t\t\t\t\t\t".'
'."\n\t\t\t\t\t".''."\n\t\t\t\t".'
'."\n"; + +?> +
+
+ +
+ + + + + + + + + + + + + + + + + +
|
+
+
+
+

+ + + + +
+ +query('SELECT * FROM '.$db->prefix.'groups WHERE g_id='.$base_group) or error('Unable to fetch user group info', __FILE__, __LINE__, $db->error()); + $group = $db->fetch_assoc($result); + + $mode = 'add'; + } + else // We are editing a group + { + $group_id = intval($_GET['edit_group']); + if ($group_id < 1) + message($lang_common['Bad request']); + + $result = $db->query('SELECT * FROM '.$db->prefix.'groups WHERE g_id='.$group_id) or error('Unable to fetch user group info', __FILE__, __LINE__, $db->error()); + if (!$db->num_rows($result)) + message($lang_common['Bad request']); + + $group = $db->fetch_assoc($result); + + $mode = 'edit'; + } + + + $page_title = array(pun_htmlspecialchars($pun_config['o_board_title']), $lang_admin_common['Admin'], $lang_admin_common['User groups']); + $required_fields = array('req_title' => $lang_admin_groups['Group title label']); + $focus_element = array('groups2', 'req_title'); + define('PUN_ACTIVE_PAGE', 'admin'); + require PUN_ROOT.'header.php'; + + generate_admin_menu('groups'); + +?> +
+

+
+
+

+
+ + + +
+ +
+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + +
+ tabindex="3" />     tabindex="4" />  + +
+ tabindex="5" />     tabindex="6" />  + +
+ tabindex="5" />     tabindex="6" />  + +
+ tabindex="5" />     tabindex="6" />  + +
+ tabindex="5" />     tabindex="6" />  + +
+ tabindex="3" />     tabindex="4" />  + +
+ tabindex="3" />     tabindex="4" />  + +
+ tabindex="5" />     tabindex="6" />  + +
+ tabindex="7" />     tabindex="8" />  + +
+ tabindex="11" />     tabindex="12" />  + +
+ tabindex="13" />     tabindex="14" />  + +
+ tabindex="15" />     tabindex="16" />  + +
+ tabindex="17" />     tabindex="18" />  + +
+ tabindex="19" />     tabindex="20" />  + +
+ tabindex="21" />     tabindex="22" />  + +
+ tabindex="21" />     tabindex="22" />  + +
+ + +
+ + +
+ + +
+

+
+
+
+

+
+
+
+
+ +escape($user_title).'\'' : 'NULL'; + + if ($_POST['mode'] == 'add') + { + $result = $db->query('SELECT 1 FROM '.$db->prefix.'groups WHERE g_title=\''.$db->escape($title).'\'') or error('Unable to check group title collision', __FILE__, __LINE__, $db->error()); + if ($db->num_rows($result)) + message(sprintf($lang_admin_groups['Title already exists message'], pun_htmlspecialchars($title))); + + $db->query('INSERT INTO '.$db->prefix.'groups (g_title, g_user_title, g_moderator, g_mod_edit_users, g_mod_rename_users, g_mod_change_passwords, g_mod_ban_users, g_read_board, g_view_users, g_post_replies, g_post_topics, g_edit_posts, g_delete_posts, g_delete_topics, g_set_title, g_search, g_search_users, g_send_email, g_post_flood, g_search_flood, g_email_flood) VALUES(\''.$db->escape($title).'\', '.$user_title.', '.$moderator.', '.$mod_edit_users.', '.$mod_rename_users.', '.$mod_change_passwords.', '.$mod_ban_users.', '.$read_board.', '.$view_users.', '.$post_replies.', '.$post_topics.', '.$edit_posts.', '.$delete_posts.', '.$delete_topics.', '.$set_title.', '.$search.', '.$search_users.', '.$send_email.', '.$post_flood.', '.$search_flood.', '.$email_flood.')') or error('Unable to add group', __FILE__, __LINE__, $db->error()); + $new_group_id = $db->insert_id(); + + // Now lets copy the forum specific permissions from the group which this group is based on + $result = $db->query('SELECT forum_id, read_forum, post_replies, post_topics FROM '.$db->prefix.'forum_perms WHERE group_id='.intval($_POST['base_group'])) or error('Unable to fetch group forum permission list', __FILE__, __LINE__, $db->error()); + while ($cur_forum_perm = $db->fetch_assoc($result)) + $db->query('INSERT INTO '.$db->prefix.'forum_perms (group_id, forum_id, read_forum, post_replies, post_topics) VALUES('.$new_group_id.', '.$cur_forum_perm['forum_id'].', '.$cur_forum_perm['read_forum'].', '.$cur_forum_perm['post_replies'].', '.$cur_forum_perm['post_topics'].')') or error('Unable to insert group forum permissions', __FILE__, __LINE__, $db->error()); + } + else + { + $result = $db->query('SELECT 1 FROM '.$db->prefix.'groups WHERE g_title=\''.$db->escape($title).'\' AND g_id!='.intval($_POST['group_id'])) or error('Unable to check group title collision', __FILE__, __LINE__, $db->error()); + if ($db->num_rows($result)) + message(sprintf($lang_admin_groups['Title already exists message'], pun_htmlspecialchars($title))); + + $db->query('UPDATE '.$db->prefix.'groups SET g_title=\''.$db->escape($title).'\', g_user_title='.$user_title.', g_moderator='.$moderator.', g_mod_edit_users='.$mod_edit_users.', g_mod_rename_users='.$mod_rename_users.', g_mod_change_passwords='.$mod_change_passwords.', g_mod_ban_users='.$mod_ban_users.', g_read_board='.$read_board.', g_view_users='.$view_users.', g_post_replies='.$post_replies.', g_post_topics='.$post_topics.', g_edit_posts='.$edit_posts.', g_delete_posts='.$delete_posts.', g_delete_topics='.$delete_topics.', g_set_title='.$set_title.', g_search='.$search.', g_search_users='.$search_users.', g_send_email='.$send_email.', g_post_flood='.$post_flood.', g_search_flood='.$search_flood.', g_email_flood='.$email_flood.' WHERE g_id='.intval($_POST['group_id'])) or error('Unable to update group', __FILE__, __LINE__, $db->error()); + } + + // Regenerate the quick jump cache + if (!defined('FORUM_CACHE_FUNCTIONS_LOADED')) + require PUN_ROOT.'include/cache.php'; + + generate_quickjump_cache(); + + if ($_POST['mode'] == 'edit') + redirect('admin_groups.php', $lang_admin_groups['Group edited redirect']); + else + redirect('admin_groups.php', $lang_admin_groups['Group added redirect']); +} + + +// Set default group +else if (isset($_POST['set_default_group'])) +{ + confirm_referrer('admin_groups.php'); + + $group_id = intval($_POST['default_group']); + + // Make sure it's not the admin or guest groups + if ($group_id == PUN_ADMIN || $group_id == PUN_GUEST) + message($lang_common['Bad request']); + + // Make sure it's not a moderator group + $result = $db->query('SELECT 1 FROM '.$db->prefix.'groups WHERE g_id='.$group_id.' AND g_moderator=0') or error('Unable to check group moderator status', __FILE__, __LINE__, $db->error()); + if (!$db->num_rows($result)) + message($lang_common['Bad request']); + + $db->query('UPDATE '.$db->prefix.'config SET conf_value='.$group_id.' WHERE conf_name=\'o_default_user_group\'') or error('Unable to update board config', __FILE__, __LINE__, $db->error()); + + // Regenerate the config cache + if (!defined('FORUM_CACHE_FUNCTIONS_LOADED')) + require PUN_ROOT.'include/cache.php'; + + generate_config_cache(); + + redirect('admin_groups.php', $lang_admin_groups['Default group redirect']); +} + + +// Remove a group +else if (isset($_GET['del_group'])) +{ + confirm_referrer('admin_groups.php'); + + $group_id = isset($_POST['group_to_delete']) ? intval($_POST['group_to_delete']) : intval($_GET['del_group']); + if ($group_id < 5) + message($lang_common['Bad request']); + + // Make sure we don't remove the default group + if ($group_id == $pun_config['o_default_user_group']) + message($lang_admin_groups['Cannot remove default message']); + + // Check if this group has any members + $result = $db->query('SELECT g.g_title, COUNT(u.id) FROM '.$db->prefix.'groups AS g INNER JOIN '.$db->prefix.'users AS u ON g.g_id=u.group_id WHERE g.g_id='.$group_id.' GROUP BY g.g_id, g_title') or error('Unable to fetch group info', __FILE__, __LINE__, $db->error()); + + // If the group doesn't have any members or if we've already selected a group to move the members to + if (!$db->num_rows($result) || isset($_POST['del_group'])) + { + if (isset($_POST['del_group_comply']) || isset($_POST['del_group'])) + { + if (isset($_POST['del_group'])) + { + $move_to_group = intval($_POST['move_to_group']); + $db->query('UPDATE '.$db->prefix.'users SET group_id='.$move_to_group.' WHERE group_id='.$group_id) or error('Unable to move users into group', __FILE__, __LINE__, $db->error()); + } + + // Delete the group and any forum specific permissions + $db->query('DELETE FROM '.$db->prefix.'groups WHERE g_id='.$group_id) or error('Unable to delete group', __FILE__, __LINE__, $db->error()); + $db->query('DELETE FROM '.$db->prefix.'forum_perms WHERE group_id='.$group_id) or error('Unable to delete group forum permissions', __FILE__, __LINE__, $db->error()); + + // Regenerate the quick jump cache + if (!defined('FORUM_CACHE_FUNCTIONS_LOADED')) + require PUN_ROOT.'include/cache.php'; + + generate_quickjump_cache(); + + redirect('admin_groups.php', $lang_admin_groups['Group removed redirect']); + } + else + { + $result = $db->query('SELECT g_title FROM '.$db->prefix.'groups WHERE g_id='.$group_id) or error('Unable to fetch group title', __FILE__, __LINE__, $db->error()); + $group_title = $db->result($result); + + $page_title = array(pun_htmlspecialchars($pun_config['o_board_title']), $lang_admin_common['Admin'], $lang_admin_common['User groups']); + define('PUN_ACTIVE_PAGE', 'admin'); + require PUN_ROOT.'header.php'; + + generate_admin_menu('groups'); + +?> +
+

+
+
+
+ +
+ +
+

+

+
+
+
+

+
+
+
+
+ +fetch_row($result); + + $page_title = array(pun_htmlspecialchars($pun_config['o_board_title']), $lang_admin_common['Admin'], $lang_admin_common['User groups']); + define('PUN_ACTIVE_PAGE', 'admin'); + require PUN_ROOT.'header.php'; + + generate_admin_menu('groups'); + +?> +
+

+
+
+
+
+ +
+

+ +
+
+
+

+
+
+
+
+ + +
+

+
+
+
+
+ +
+ + + + + +
+ + +
+
+
+
+
+
+ +
+ + + + + +
+ + +
+
+
+
+
+
+ +

+
+
+
+
+ +
+

+ +query('SELECT g_id, g_title FROM '.$db->prefix.'groups ORDER BY g_id') or error('Unable to fetch user group list', __FILE__, __LINE__, $db->error()); + +while ($cur_group = $db->fetch_assoc($result)) + echo "\t\t\t\t\t\t\t\t".''."\n"; + +?> +
'.$lang_admin_groups['Edit link'].''.(($cur_group['g_id'] > PUN_MEMBER) ? ' | '.$lang_admin_groups['Delete link'].'' : '').''.pun_htmlspecialchars($cur_group['g_title']).'
+
+
+
+
+
+
+
+ +=')) + message($lang_admin_index['Running latest version message']); + else + message(sprintf($lang_admin_index['New version available message'], 'FluxBB.org')); +} + + +// Show phpinfo() output +else if ($action == 'phpinfo' && $pun_user['g_id'] == PUN_ADMIN) +{ + // Is phpinfo() a disabled function? + if (strpos(strtolower((string) ini_get('disable_functions')), 'phpinfo') !== false) + message($lang_admin_index['PHPinfo disabled message']); + + phpinfo(); + exit; +} + + +// Get the server load averages (if possible) +if (@file_exists('/proc/loadavg') && is_readable('/proc/loadavg')) +{ + // We use @ just in case + $fh = @fopen('/proc/loadavg', 'r'); + $load_averages = @fread($fh, 64); + @fclose($fh); + + if (($fh = @fopen('/proc/loadavg', 'r'))) + { + $load_averages = fread($fh, 64); + fclose($fh); + } + else + $load_averages = ''; + + $load_averages = @explode(' ', $load_averages); + $server_load = isset($load_averages[2]) ? $load_averages[0].' '.$load_averages[1].' '.$load_averages[2] : $lang_admin_index['Not available']; +} +else if (!in_array(PHP_OS, array('WINNT', 'WIN32')) && preg_match('/averages?: ([0-9\.]+),?\s+([0-9\.]+),?\s+([0-9\.]+)/i', @exec('uptime'), $load_averages)) + $server_load = $load_averages[1].' '.$load_averages[2].' '.$load_averages[3]; +else + $server_load = $lang_admin_index['Not available']; + + +// Get number of current visitors +$result = $db->query('SELECT COUNT(user_id) FROM '.$db->prefix.'online WHERE idle=0') or error('Unable to fetch online count', __FILE__, __LINE__, $db->error()); +$num_online = $db->result($result); + + +// Collect some additional info about MySQL +if ($db_type == 'mysql' || $db_type == 'mysqli' || $db_type == 'mysql_innodb' || $db_type == 'mysqli_innodb') +{ + // Calculate total db size/row count + $result = $db->query('SHOW TABLE STATUS FROM `'.$db_name.'`') or error('Unable to fetch table status', __FILE__, __LINE__, $db->error()); + + $total_records = $total_size = 0; + while ($status = $db->fetch_assoc($result)) + { + $total_records += $status['Rows']; + $total_size += $status['Data_length'] + $status['Index_length']; + } + + $total_size = file_size($total_size); +} + + +// Check for the existence of various PHP opcode caches/optimizers +if (function_exists('mmcache')) + $php_accelerator = ''.$lang_admin_index['Turck MMCache'].''; +else if (isset($_PHPA)) + $php_accelerator = ''.$lang_admin_index['ionCube PHP Accelerator'].''; +else if (ini_get('apc.enabled')) + $php_accelerator =''.$lang_admin_index['Alternative PHP Cache (APC)'].''; +else if (ini_get('zend_optimizer.optimization_level')) + $php_accelerator = ''.$lang_admin_index['Zend Optimizer'].''; +else if (ini_get('eaccelerator.enable')) + $php_accelerator = ''.$lang_admin_index['eAccelerator'].''; +else if (ini_get('xcache.cacher')) + $php_accelerator = ''.$lang_admin_index['XCache'].''; +else + $php_accelerator = $lang_admin_index['NA']; + + +$page_title = array(pun_htmlspecialchars($pun_config['o_board_title']), $lang_admin_common['Admin'], $lang_admin_common['Index']); +define('PUN_ACTIVE_PAGE', 'admin'); +require PUN_ROOT.'header.php'; + +generate_admin_menu('index'); + +?> +
+

+
+
+

+

+  -
+  -
+  -
+  -
+  -
+  -
+  -
+  -
+  - +

+
+
+ +

+
+
+
+
+
+ '.$lang_admin_index['Check for upgrade'].'') ?>
+
+
+
+ +
+
+
+
+ '.$lang_admin_index['Show info'].'') ?>
+ +
+
+
+ get_version())."\n" ?> +
+
+
+
+
+
+
+
+ + +
+ +truncate_table('search_matches') or error('Unable to empty search index match table', __FILE__, __LINE__, $db->error()); + $db->truncate_table('search_words') or error('Unable to empty search index words table', __FILE__, __LINE__, $db->error()); + + // Reset the sequence for the search words (not needed for SQLite) + switch ($db_type) + { + case 'mysql': + case 'mysqli': + case 'mysql_innodb': + case 'mysqli_innodb': + $result = $db->query('ALTER TABLE '.$db->prefix.'search_words auto_increment=1') or error('Unable to update table auto_increment', __FILE__, __LINE__, $db->error()); + break; + + case 'pgsql'; + $result = $db->query('SELECT setval(\''.$db->prefix.'search_words_id_seq\', 1, false)') or error('Unable to update sequence', __FILE__, __LINE__, $db->error()); + } + } + + $page_title = array(pun_htmlspecialchars($pun_config['o_board_title']), $lang_admin_maintenance['Rebuilding search index']); + +?> + + + + + +<?php echo generate_page_title($page_title) ?> + + + + +

+
+ +query('SELECT p.id, p.message, t.subject, t.first_post_id FROM '.$db->prefix.'posts AS p INNER JOIN '.$db->prefix.'topics AS t ON t.id=p.topic_id WHERE p.id >= '.$start_at.' ORDER BY p.id ASC LIMIT '.$per_page) or error('Unable to fetch posts', __FILE__, __LINE__, $db->error()); + + $end_at = 0; + while ($cur_item = $db->fetch_assoc($result)) + { + echo '

'.sprintf($lang_admin_maintenance['Processing post'], $cur_item['id']).'

'."\n"; + + if ($cur_item['id'] == $cur_item['first_post_id']) + update_search_index('post', $cur_item['id'], $cur_item['message'], $cur_item['subject']); + else + update_search_index('post', $cur_item['id'], $cur_item['message']); + + $end_at = $cur_item['id']; + } + + // Check if there is more work to do + if ($end_at > 0) + { + $result = $db->query('SELECT id FROM '.$db->prefix.'posts WHERE id > '.$end_at.' ORDER BY id ASC LIMIT 1') or error('Unable to fetch next ID', __FILE__, __LINE__, $db->error()); + + if ($db->num_rows($result) > 0) + $query_str = '?i_per_page='.$per_page.'&i_start_at='.$db->result($result); + } + + $db->end_transaction(); + $db->close(); + + exit('

'.sprintf($lang_admin_maintenance['Javascript redirect failed'], ''.$lang_admin_maintenance['Click here'].'').'

'); +} + + +// Get the first post ID from the db +$result = $db->query('SELECT id FROM '.$db->prefix.'posts ORDER BY id ASC LIMIT 1') or error('Unable to fetch topic info', __FILE__, __LINE__, $db->error()); +if ($db->num_rows($result)) + $first_id = $db->result($result); + +$page_title = array(pun_htmlspecialchars($pun_config['o_board_title']), $lang_admin_common['Admin'], $lang_admin_common['Maintenance']); +define('PUN_ACTIVE_PAGE', 'admin'); +require PUN_ROOT.'header.php'; + +generate_admin_menu('maintenance'); + +?> +
+

+
+
+
+
+ +
+

'.$lang_admin_common['Maintenance mode'].'') ?>

+ + + + + + + + + + + + + +
+ + +
+ + +
+    +
+

+
+
+
+
+
+
+
+
+ + pun_trim($_POST['form']['board_title']), + 'board_desc' => pun_trim($_POST['form']['board_desc']), + 'base_url' => pun_trim($_POST['form']['base_url']), + 'default_timezone' => floatval($_POST['form']['default_timezone']), + 'default_dst' => $_POST['form']['default_dst'] != '1' ? '0' : '1', + 'default_lang' => preg_replace('#[\.\\\/]#', '', pun_trim($_POST['form']['default_lang'])), + 'default_style' => preg_replace('#[\.\\\/]#', '', pun_trim($_POST['form']['default_style'])), + 'time_format' => pun_trim($_POST['form']['time_format']), + 'date_format' => pun_trim($_POST['form']['date_format']), + 'timeout_visit' => intval($_POST['form']['timeout_visit']), + 'timeout_online' => intval($_POST['form']['timeout_online']), + 'redirect_delay' => intval($_POST['form']['redirect_delay']), + 'show_version' => $_POST['form']['show_version'] != '1' ? '0' : '1', + 'show_user_info' => $_POST['form']['show_user_info'] != '1' ? '0' : '1', + 'show_post_count' => $_POST['form']['show_post_count'] != '1' ? '0' : '1', + 'smilies' => $_POST['form']['smilies'] != '1' ? '0' : '1', + 'smilies_sig' => $_POST['form']['smilies_sig'] != '1' ? '0' : '1', + 'make_links' => $_POST['form']['make_links'] != '1' ? '0' : '1', + 'topic_review' => intval($_POST['form']['topic_review']), + 'disp_topics_default' => intval($_POST['form']['disp_topics_default']), + 'disp_posts_default' => intval($_POST['form']['disp_posts_default']), + 'indent_num_spaces' => intval($_POST['form']['indent_num_spaces']), + 'quote_depth' => intval($_POST['form']['quote_depth']), + 'quickpost' => $_POST['form']['quickpost'] != '1' ? '0' : '1', + 'users_online' => $_POST['form']['users_online'] != '1' ? '0' : '1', + 'censoring' => $_POST['form']['censoring'] != '1' ? '0' : '1', + 'signatures' => $_POST['form']['signatures'] != '1' ? '0' : '1', + 'ranks' => $_POST['form']['ranks'] != '1' ? '0' : '1', + 'show_dot' => $_POST['form']['show_dot'] != '1' ? '0' : '1', + 'topic_views' => $_POST['form']['topic_views'] != '1' ? '0' : '1', + 'quickjump' => $_POST['form']['quickjump'] != '1' ? '0' : '1', + 'gzip' => $_POST['form']['gzip'] != '1' ? '0' : '1', + 'search_all_forums' => $_POST['form']['search_all_forums'] != '1' ? '0' : '1', + 'additional_navlinks' => pun_trim($_POST['form']['additional_navlinks']), + 'feed_type' => intval($_POST['form']['feed_type']), + 'report_method' => intval($_POST['form']['report_method']), + 'mailing_list' => pun_trim($_POST['form']['mailing_list']), + 'avatars' => $_POST['form']['avatars'] != '1' ? '0' : '1', + 'avatars_dir' => pun_trim($_POST['form']['avatars_dir']), + 'avatars_width' => intval($_POST['form']['avatars_width']), + 'avatars_height' => intval($_POST['form']['avatars_height']), + 'avatars_size' => intval($_POST['form']['avatars_size']), + 'admin_email' => strtolower(pun_trim($_POST['form']['admin_email'])), + 'webmaster_email' => strtolower(pun_trim($_POST['form']['webmaster_email'])), + 'subscriptions' => $_POST['form']['subscriptions'] != '1' ? '0' : '1', + 'smtp_host' => pun_trim($_POST['form']['smtp_host']), + 'smtp_user' => pun_trim($_POST['form']['smtp_user']), + 'smtp_pass' => pun_trim($_POST['form']['smtp_pass']), + 'smtp_ssl' => $_POST['form']['smtp_ssl'] != '1' ? '0' : '1', + 'regs_allow' => $_POST['form']['regs_allow'] != '1' ? '0' : '1', + 'regs_verify' => $_POST['form']['regs_verify'] != '1' ? '0' : '1', + 'regs_report' => $_POST['form']['regs_report'] != '1' ? '0' : '1', + 'rules' => $_POST['form']['rules'] != '1' ? '0' : '1', + 'rules_message' => pun_trim($_POST['form']['rules_message']), + 'default_email_setting' => intval($_POST['form']['default_email_setting']), + 'announcement' => $_POST['form']['announcement'] != '1' ? '0' : '1', + 'announcement_message' => pun_trim($_POST['form']['announcement_message']), + 'maintenance' => $_POST['form']['maintenance'] != '1' ? '0' : '1', + 'maintenance_message' => pun_trim($_POST['form']['maintenance_message']), + ); + + if ($form['board_title'] == '') + message($lang_admin_options['Must enter title message']); + + // Make sure base_url doesn't end with a slash + if (substr($form['base_url'], -1) == '/') + $form['base_url'] = substr($form['base_url'], 0, -1); + + if (!file_exists(PUN_ROOT.'lang/'.$form['default_lang'].'/common.php')) + message($lang_common['Bad request']); + if (!file_exists(PUN_ROOT.'style/'.$form['default_style'].'.css')) + message($lang_common['Bad request']); + + if ($form['time_format'] == '') + $form['time_format'] = 'H:i:s'; + + if ($form['date_format'] == '') + $form['date_format'] = 'Y-m-d'; + + + require PUN_ROOT.'include/email.php'; + + if (!is_valid_email($form['admin_email'])) + message($lang_admin_options['Invalid e-mail message']); + + if (!is_valid_email($form['webmaster_email'])) + message($lang_admin_options['Invalid webmaster e-mail message']); + + if ($form['mailing_list'] != '') + $form['mailing_list'] = strtolower(preg_replace('/\s/S', '', $form['mailing_list'])); + + // Make sure avatars_dir doesn't end with a slash + if (substr($form['avatars_dir'], -1) == '/') + $form['avatars_dir'] = substr($form['avatars_dir'], 0, -1); + + if ($form['additional_navlinks'] != '') + $form['additional_navlinks'] = pun_trim(pun_linebreaks($form['additional_navlinks'])); + + if ($form['announcement_message'] != '') + $form['announcement_message'] = pun_linebreaks($form['announcement_message']); + else + { + $form['announcement_message'] = $lang_admin_options['Enter announcement here']; + $form['announcement'] = '0'; + } + + if ($form['rules_message'] != '') + $form['rules_message'] = pun_linebreaks($form['rules_message']); + else + { + $form['rules_message'] = $lang_admin_options['Enter rules here']; + $form['rules'] = '0'; + } + + if ($form['maintenance_message'] != '') + $form['maintenance_message'] = pun_linebreaks($form['maintenance_message']); + else + { + $form['maintenance_message'] = $lang_admin_options['Default maintenance message']; + $form['maintenance'] = '0'; + } + + // Make sure the number of displayed topics and posts is between 3 and 75 + if ($form['disp_topics_default'] < 3) + $form['disp_topics_default'] = 3; + else if ($form['disp_topics_default'] > 75) + $form['disp_topics_default'] = 75; + + if ($form['disp_posts_default'] < 3) + $form['disp_posts_default'] = 3; + else if ($form['disp_posts_default'] > 75) + $form['disp_posts_default'] = 75; + + if ($form['feed_type'] < 0 || $form['feed_type'] > 2) + message($lang_common['Bad request']); + + if ($form['report_method'] < 0 || $form['report_method'] > 2) + message($lang_common['Bad request']); + + if ($form['default_email_setting'] < 0 || $form['default_email_setting'] > 2) + message($lang_common['Bad request']); + + if ($form['timeout_online'] >= $form['timeout_visit']) + message($lang_admin_options['Timeout error message']); + + foreach ($form as $key => $input) + { + // Only update values that have changed + if (array_key_exists('o_'.$key, $pun_config) && $pun_config['o_'.$key] != $input) + { + if ($input != '' || is_int($input)) + $value = '\''.$db->escape($input).'\''; + else + $value = 'NULL'; + + $db->query('UPDATE '.$db->prefix.'config SET conf_value='.$value.' WHERE conf_name=\'o_'.$db->escape($key).'\'') or error('Unable to update board config', __FILE__, __LINE__, $db->error()); + } + } + + // Regenerate the config cache + if (!defined('FORUM_CACHE_FUNCTIONS_LOADED')) + require PUN_ROOT.'include/cache.php'; + + generate_config_cache(); + + redirect('admin_options.php', $lang_admin_options['Options updated redirect']); +} + +$page_title = array(pun_htmlspecialchars($pun_config['o_board_title']), $lang_admin_common['Admin'], $lang_admin_common['Options']); +define('PUN_ACTIVE_PAGE', 'admin'); +require PUN_ROOT.'header.php'; + +generate_admin_menu('options'); + +?> +
+

+
+
+

+
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ + +
+ + +
+ + +
+ />     />  + +
+ + +
+ + +
+
+
+
+ +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ + '.$lang_admin_options['PHP manual'].'') ?> +
+ + '.$lang_admin_options['PHP manual'].'') ?> +
+ + +
+ + +
+ + +
+
+
+
+
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ />     />  + +
+ />     />  + +
+ />     />  + +
+ />     />  + +
+ />     />  + +
+ />     />  + +
+ + +
+ + +
+ + +
+ + +
+ + +
+
+
+
+
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ />     />  + +
+ />     />  + +
+ />     />  + '.$lang_admin_common['Censoring'].'') ?> +
+ />     />  + +
+ />     />  + '.$lang_admin_common['Ranks'].'') ?> +
+ />     />  + +
+ />     />  + +
+ />     />  + +
+ />     />  + +
+ />     />  + +
+ + +
+ />     />     />  + +
+
+
+
+
+
+ +
+ + + + + + + + + +
+ />     />     />  + +
+ + +
+
+
+
+
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ />     />  + +
+ + +
+ + +
+ + +
+ + +
+
+
+
+
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ + +
+ />     />  + +
+ + +
+ + +
+ + +
+ />     />  + +
+
+
+
+
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ />     />  + +
+ />     />  + +
+ />     />  + +
+ />     />  + +
+ + +
+ + /> 
+ /> 
+ /> 
+
+
+
+
+
+
+ +
+ + + + + + + + + +
+ />     />  + +
+ + +
+
+
+
+
+
+ +
+ + + + + + + + + +
+ />     />  + +
+ + +
+
+
+
+

+
+
+
+
+ + $input) + { + // Only update values that have changed + if (array_key_exists('p_'.$key, $pun_config) && $pun_config['p_'.$key] != $input) + $db->query('UPDATE '.$db->prefix.'config SET conf_value='.$input.' WHERE conf_name=\'p_'.$db->escape($key).'\'') or error('Unable to update board config', __FILE__, __LINE__, $db->error()); + } + + // Regenerate the config cache + if (!defined('FORUM_CACHE_FUNCTIONS_LOADED')) + require PUN_ROOT.'include/cache.php'; + + generate_config_cache(); + + redirect('admin_permissions.php', $lang_admin_permissions['Perms updated redirect']); +} + +$page_title = array(pun_htmlspecialchars($pun_config['o_board_title']), $lang_admin_common['Admin'], $lang_admin_common['Permissions']); +define('PUN_ACTIVE_PAGE', 'admin'); +require PUN_ROOT.'header.php'; + +generate_admin_menu('permissions'); + +?> +
+

+
+
+

+
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ />     />  + +
+ />     />  + +
+ />     />  + +
+ />     />  + +
+ />     />  + +
+
+
+
+
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ />     />  + +
+ />     />  + +
+ />     />  + +
+ + +
+ + +
+
+
+
+
+
+ +
+ + + + + + + + + +
+ />     />  + +
+ />     />  + +
+
+
+
+

+
+
+
+
+ +query('SELECT id FROM '.$db->prefix.'forums') or error('Unable to fetch forum list', __FILE__, __LINE__, $db->error()); + $num_forums = $db->num_rows($result); + + for ($i = 0; $i < $num_forums; ++$i) + { + $fid = $db->result($result, $i); + + prune($fid, $prune_sticky, $prune_date); + update_forum($fid); + } + } + else + { + $prune_from = intval($prune_from); + prune($prune_from, $prune_sticky, $prune_date); + update_forum($prune_from); + } + + // Locate any "orphaned redirect topics" and delete them + $result = $db->query('SELECT t1.id FROM '.$db->prefix.'topics AS t1 LEFT JOIN '.$db->prefix.'topics AS t2 ON t1.moved_to=t2.id WHERE t2.id IS NULL AND t1.moved_to IS NOT NULL') or error('Unable to fetch redirect topics', __FILE__, __LINE__, $db->error()); + $num_orphans = $db->num_rows($result); + + if ($num_orphans) + { + for ($i = 0; $i < $num_orphans; ++$i) + $orphans[] = $db->result($result, $i); + + $db->query('DELETE FROM '.$db->prefix.'topics WHERE id IN('.implode(',', $orphans).')') or error('Unable to delete redirect topics', __FILE__, __LINE__, $db->error()); + } + + redirect('admin_prune.php', $lang_admin_prune['Posts pruned redirect']); + } + + $prune_days = trim($_POST['req_prune_days']); + if ($prune_days == '' || preg_match('/[^0-9]/', $prune_days)) + message($lang_admin_prune['Must be integer message']); + + $prune_date = time() - ($prune_days * 86400); + + // Concatenate together the query for counting number of topics to prune + $sql = 'SELECT COUNT(id) FROM '.$db->prefix.'topics WHERE last_post<'.$prune_date.' AND moved_to IS NULL'; + + if ($prune_sticky == '0') + $sql .= ' AND sticky=\'0\''; + + if ($prune_from != 'all') + { + $prune_from = intval($prune_from); + $sql .= ' AND forum_id='.$prune_from; + + // Fetch the forum name (just for cosmetic reasons) + $result = $db->query('SELECT forum_name FROM '.$db->prefix.'forums WHERE id='.$prune_from) or error('Unable to fetch forum name', __FILE__, __LINE__, $db->error()); + $forum = '"'.pun_htmlspecialchars($db->result($result)).'"'; + } + else + $forum = $lang_admin_prune['All forums']; + + $result = $db->query($sql) or error('Unable to fetch topic prune count', __FILE__, __LINE__, $db->error()); + $num_topics = $db->result($result); + + if (!$num_topics) + message(sprintf($lang_admin_prune['No old topics message'], $prune_days)); + + + $page_title = array(pun_htmlspecialchars($pun_config['o_board_title']), $lang_admin_common['Admin'], $lang_admin_common['Prune']); + define('PUN_ACTIVE_PAGE', 'admin'); + require PUN_ROOT.'header.php'; + + generate_admin_menu('prune'); + +?> +
+

+
+
+
+ + + +
+ +
+

+

+
+
+
+

+
+
+
+
+ + $lang_admin_prune['Days old label']); + $focus_element = array('prune', 'req_prune_days'); + define('PUN_ACTIVE_PAGE', 'admin'); + require PUN_ROOT.'header.php'; + + generate_admin_menu('prune'); + +?> +
+

+
+
+
+ +
+ +
+ + + + + + + + + + + + + +
+ + +
+       + +
+ + +
+

'.$lang_admin_common['Maintenance mode'].'') ?>

+
+
+
+
+
+
+
+
+ +query('SELECT 1 FROM '.$db->prefix.'ranks WHERE min_posts='.$min_posts) or error('Unable to fetch rank info', __FILE__, __LINE__, $db->error()); + if ($db->num_rows($result)) + message(sprintf($lang_admin_ranks['Dupe min posts message'], $min_posts)); + + $db->query('INSERT INTO '.$db->prefix.'ranks (rank, min_posts) VALUES(\''.$db->escape($rank).'\', '.$min_posts.')') or error('Unable to add rank', __FILE__, __LINE__, $db->error()); + + // Regenerate the ranks cache + if (!defined('FORUM_CACHE_FUNCTIONS_LOADED')) + require PUN_ROOT.'include/cache.php'; + + generate_ranks_cache(); + + redirect('admin_ranks.php', $lang_admin_ranks['Rank added redirect']); +} + + +// Update a rank +else if (isset($_POST['update'])) +{ + confirm_referrer('admin_ranks.php'); + + $id = intval(key($_POST['update'])); + + $rank = pun_trim($_POST['rank'][$id]); + $min_posts = trim($_POST['min_posts'][$id]); + + if ($rank == '') + message($lang_admin_ranks['Must enter title message']); + + if ($min_posts == '' || preg_match('/[^0-9]/', $min_posts)) + message($lang_admin_ranks['Must be integer message']); + + // Make sure there isn't already a rank with the same min_posts value + $result = $db->query('SELECT 1 FROM '.$db->prefix.'ranks WHERE id!='.$id.' AND min_posts='.$min_posts) or error('Unable to fetch rank info', __FILE__, __LINE__, $db->error()); + if ($db->num_rows($result)) + message(sprintf($lang_admin_ranks['Dupe min posts message'], $min_posts)); + + $db->query('UPDATE '.$db->prefix.'ranks SET rank=\''.$db->escape($rank).'\', min_posts='.$min_posts.' WHERE id='.$id) or error('Unable to update rank', __FILE__, __LINE__, $db->error()); + + // Regenerate the ranks cache + if (!defined('FORUM_CACHE_FUNCTIONS_LOADED')) + require PUN_ROOT.'include/cache.php'; + + generate_ranks_cache(); + + redirect('admin_ranks.php', $lang_admin_ranks['Rank updated redirect']); +} + + +// Remove a rank +else if (isset($_POST['remove'])) +{ + confirm_referrer('admin_ranks.php'); + + $id = intval(key($_POST['remove'])); + + $db->query('DELETE FROM '.$db->prefix.'ranks WHERE id='.$id) or error('Unable to delete rank', __FILE__, __LINE__, $db->error()); + + // Regenerate the ranks cache + if (!defined('FORUM_CACHE_FUNCTIONS_LOADED')) + require PUN_ROOT.'include/cache.php'; + + generate_ranks_cache(); + + redirect('admin_ranks.php', $lang_admin_ranks['Rank removed redirect']); +} + +$page_title = array(pun_htmlspecialchars($pun_config['o_board_title']), $lang_admin_common['Admin'], $lang_admin_common['Ranks']); +$focus_element = array('ranks', 'new_rank'); +define('PUN_ACTIVE_PAGE', 'admin'); +require PUN_ROOT.'header.php'; + +generate_admin_menu('ranks'); + +?> +
+

+
+
+
+
+ +
+

'.$lang_admin_common['Options'].'') ?>

+ + + + + + + + + + + + + + + +
+
+
+
+
+
+ +
+query('SELECT id, rank, min_posts FROM '.$db->prefix.'ranks ORDER BY min_posts') or error('Unable to fetch rank list', __FILE__, __LINE__, $db->error()); +if ($db->num_rows($result)) +{ + +?> + + + + + + + + + +fetch_assoc($result)) + echo "\t\t\t\t\t\t\t\t".''."\n"; + +?> + +
 
+'.$lang_admin_ranks['No ranks in list'].'

'."\n"; + +?> +
+
+
+
+
+
+
+ +query('SELECT zapped FROM '.$db->prefix.'reports WHERE id='.$zap_id) or error('Unable to fetch report info', __FILE__, __LINE__, $db->error()); + $zapped = $db->result($result); + + if ($zapped == '') + $db->query('UPDATE '.$db->prefix.'reports SET zapped='.time().', zapped_by='.$pun_user['id'].' WHERE id='.$zap_id) or error('Unable to zap report', __FILE__, __LINE__, $db->error()); + + redirect('admin_reports.php', $lang_admin_reports['Report zapped redirect']); +} + + +$page_title = array(pun_htmlspecialchars($pun_config['o_board_title']), $lang_admin_common['Admin'], $lang_admin_common['Reports']); +define('PUN_ACTIVE_PAGE', 'admin'); +require PUN_ROOT.'header.php'; + +generate_admin_menu('reports'); + +?> +
+

+
+
+query('SELECT r.id, r.topic_id, r.forum_id, r.reported_by, r.created, r.message, p.id AS pid, t.subject, f.forum_name, u.username AS reporter FROM '.$db->prefix.'reports AS r LEFT JOIN '.$db->prefix.'posts AS p ON r.post_id=p.id LEFT JOIN '.$db->prefix.'topics AS t ON r.topic_id=t.id LEFT JOIN '.$db->prefix.'forums AS f ON r.forum_id=f.id LEFT JOIN '.$db->prefix.'users AS u ON r.reported_by=u.id WHERE r.zapped IS NULL ORDER BY created DESC') or error('Unable to fetch report list', __FILE__, __LINE__, $db->error()); + +if ($db->num_rows($result)) +{ + while ($cur_report = $db->fetch_assoc($result)) + { + $reporter = ($cur_report['reporter'] != '') ? ''.pun_htmlspecialchars($cur_report['reporter']).'' : $lang_admin_reports['Deleted user']; + $forum = ($cur_report['forum_name'] != '') ? ''.pun_htmlspecialchars($cur_report['forum_name']).'' : ''.$lang_admin_reports['Deleted'].''; + $topic = ($cur_report['subject'] != '') ? '» '.pun_htmlspecialchars($cur_report['subject']).'' : '» '.$lang_admin_reports['Deleted'].''; + $post = str_replace("\n", '
', pun_htmlspecialchars($cur_report['message'])); + $postid = ($cur_report['pid'] != '') ? '» Post #'.$cur_report['pid'].'' : '» '.$lang_admin_reports['Deleted'].''; + $report_location = array($forum, $topic, $postid); + +?> +
+
+ +
+ + + + + + + + + +
+
+
+
+ +
+
+ +
+

+
+
+
+ +
+
+
+ +
+

+
+
+query('SELECT r.id, r.topic_id, r.forum_id, r.reported_by, r.message, r.zapped, r.zapped_by AS zapped_by_id, p.id AS pid, t.subject, f.forum_name, u.username AS reporter, u2.username AS zapped_by FROM '.$db->prefix.'reports AS r LEFT JOIN '.$db->prefix.'posts AS p ON r.post_id=p.id LEFT JOIN '.$db->prefix.'topics AS t ON r.topic_id=t.id LEFT JOIN '.$db->prefix.'forums AS f ON r.forum_id=f.id LEFT JOIN '.$db->prefix.'users AS u ON r.reported_by=u.id LEFT JOIN '.$db->prefix.'users AS u2 ON r.zapped_by=u2.id WHERE r.zapped IS NOT NULL ORDER BY zapped DESC LIMIT 10') or error('Unable to fetch report list', __FILE__, __LINE__, $db->error()); + +if ($db->num_rows($result)) +{ + while ($cur_report = $db->fetch_assoc($result)) + { + $reporter = ($cur_report['reporter'] != '') ? ''.pun_htmlspecialchars($cur_report['reporter']).'' : $lang_admin_reports['Deleted user']; + $forum = ($cur_report['forum_name'] != '') ? ''.pun_htmlspecialchars($cur_report['forum_name']).'' : ''.$lang_admin_reports['Deleted'].''; + $topic = ($cur_report['subject'] != '') ? '» '.pun_htmlspecialchars($cur_report['subject']).'' : '» '.$lang_admin_reports['Deleted'].''; + $post = str_replace("\n", '
', pun_htmlspecialchars($cur_report['message'])); + $post_id = ($cur_report['pid'] != '') ? '» Post #'.$cur_report['pid'].'' : '» '.$lang_admin_reports['Deleted'].''; + $zapped_by = ($cur_report['zapped_by'] != '') ? ''.pun_htmlspecialchars($cur_report['zapped_by']).'' : $lang_admin_reports['NA']; + $zapped_by = ($cur_report['zapped_by'] != '') ? ''.pun_htmlspecialchars($cur_report['zapped_by']).'' : $lang_admin_reports['NA']; + $report_location = array($forum, $topic, $post_id); + +?> +
+
+ +
+ + + + + + + + + +
+
+
+
+ +
+
+ +
+

+
+
+
+ +
+
+
+
+ +query('SELECT poster_ip, MAX(posted) AS last_used FROM '.$db->prefix.'posts WHERE poster_id='.$ip_stats.' GROUP BY poster_ip') or error('Unable to fetch post info', __FILE__, __LINE__, $db->error()); + $num_ips = $db->num_rows($result); + + // Determine the ip offset (based on $_GET['p']) + $num_pages = ceil($num_ips / 50); + + $p = (!isset($_GET['p']) || $_GET['p'] <= 1 || $_GET['p'] > $num_pages) ? 1 : intval($_GET['p']); + $start_from = 50 * ($p - 1); + + // Generate paging links + $paging_links = ''.$lang_common['Pages'].' '.paginate($num_pages, $p, 'admin_users.php?ip_stats='.$ip_stats ); + + $page_title = array(pun_htmlspecialchars($pun_config['o_board_title']), $lang_admin_common['Admin'], $lang_admin_common['Users'], $lang_admin_users['Results head']); + define('PUN_ACTIVE_PAGE', 'admin'); + require PUN_ROOT.'header.php'; + +?> +
+
+ +
+ +
+
+
+
+ +
+

+
+
+ + + + + + + + + + +query('SELECT poster_ip, MAX(posted) AS last_used, COUNT(id) AS used_times FROM '.$db->prefix.'posts WHERE poster_id='.$ip_stats.' GROUP BY poster_ip ORDER BY last_used DESC LIMIT '.$start_from.', 50') or error('Unable to fetch post info', __FILE__, __LINE__, $db->error()); + if ($db->num_rows($result)) + { + while ($cur_ip = $db->fetch_assoc($result)) + { + +?> + + + + + + +'."\n"; + +?> + +
'.$lang_admin_users['Results no posts found'].'
+
+
+
+ +
+
+
+ +
+ +
+
+
+query('SELECT DISTINCT poster_id, poster FROM '.$db->prefix.'posts WHERE poster_ip=\''.$db->escape($ip).'\'') or error('Unable to fetch post info', __FILE__, __LINE__, $db->error()); + $num_users = $db->num_rows($result); + + // Determine the user offset (based on $_GET['p']) + $num_pages = ceil($num_users / 50); + + $p = (!isset($_GET['p']) || $_GET['p'] <= 1 || $_GET['p'] > $num_pages) ? 1 : intval($_GET['p']); + $start_from = 50 * ($p - 1); + + // Generate paging links + $paging_links = ''.$lang_common['Pages'].' '.paginate($num_pages, $p, 'admin_users.php?show_users='.$ip); + + $page_title = array(pun_htmlspecialchars($pun_config['o_board_title']), $lang_admin_common['Admin'], $lang_admin_common['Users'], $lang_admin_users['Results head']); + define('PUN_ACTIVE_PAGE', 'admin'); + require PUN_ROOT.'header.php'; + +?> +
+
+ +
+ +
+
+
+
+ +
+

+
+
+ + + + + + + + + + + + +query('SELECT DISTINCT poster_id, poster FROM '.$db->prefix.'posts WHERE poster_ip=\''.$db->escape($ip).'\' ORDER BY poster DESC') or error('Unable to fetch post info', __FILE__, __LINE__, $db->error()); + $num_posts = $db->num_rows($result); + + if ($num_posts) + { + // Loop through users and print out some info + for ($i = 0; $i < $num_posts; ++$i) + { + list($poster_id, $poster) = $db->fetch_row($result); + + $result2 = $db->query('SELECT u.id, u.username, u.email, u.title, u.num_posts, u.admin_note, g.g_id, g.g_user_title FROM '.$db->prefix.'users AS u INNER JOIN '.$db->prefix.'groups AS g ON g.g_id=u.group_id WHERE u.id>1 AND u.id='.$poster_id) or error('Unable to fetch user info', __FILE__, __LINE__, $db->error()); + + if (($user_data = $db->fetch_assoc($result2))) + { + $user_title = get_title($user_data); + + $actions = ''.$lang_admin_users['Results view IP link'].' | '.$lang_admin_users['Results show posts link'].''; + +?> + + + + + + + + + + + + + + + + + +'."\n"; + +?> + +
'.pun_htmlspecialchars($user_data['username']).'' ?>
    
'.$lang_admin_users['Results no IP found'].'
+
+
+
+ +
+
+
+ +
+ +
+
+
+'.$last_post_after; + } + if ($last_post_before != '') + { + $query_str[] = 'last_post_before='.$last_post_before; + + $last_post_before = strtotime($last_post_before); + if ($last_post_before === false || $last_post_before == -1) + message($lang_admin_users['Invalid date time message']); + + $conditions[] = 'u.last_post<'.$last_post_before; + } + if ($registered_after != '') + { + $query_str[] = 'registered_after='.$registered_after; + + $registered_after = strtotime($registered_after); + if ($registered_after === false || $registered_after == -1) + message($lang_admin_users['Invalid date time message']); + + $conditions[] = 'u.registered>'.$registered_after; + } + if ($registered_before != '') + { + $query_str[] = 'registered_before='.$registered_before; + + $registered_before = strtotime($registered_before); + if ($registered_before === false || $registered_before == -1) + message($lang_admin_users['Invalid date time message']); + + $conditions[] = 'u.registered<'.$registered_before; + } + + $like_command = ($db_type == 'pgsql') ? 'ILIKE' : 'LIKE'; + foreach ($form as $key => $input) + { + if ($input != '' && in_array($key, array('username', 'email', 'title', 'realname', 'url', 'jabber', 'icq', 'msn', 'aim', 'yahoo', 'location', 'signature', 'admin_note'))) + { + $conditions[] = 'u.'.$db->escape($key).' '.$like_command.' \''.$db->escape(str_replace('*', '%', $input)).'\''; + $query_str[] = 'form%5B'.$key.'%5D='.urlencode($input); + } + } + + if ($posts_greater != '') + { + $query_str[] = 'posts_greater='.$posts_greater; + $conditions[] = 'u.num_posts>'.$posts_greater; + } + if ($posts_less != '') + { + $query_str[] = 'posts_less='.$posts_less; + $conditions[] = 'u.num_posts<'.$posts_less; + } + + if ($user_group > -1) + $conditions[] = 'u.group_id='.$user_group; + + // Fetch user count + $result = $db->query('SELECT COUNT(id) FROM '.$db->prefix.'users AS u LEFT JOIN '.$db->prefix.'groups AS g ON g.g_id=u.group_id WHERE u.id>1'.(!empty($conditions) ? ' AND '.implode(' AND ', $conditions) : '')) or error('Unable to fetch user info', __FILE__, __LINE__, $db->error()); + $num_users = $db->result($result); + + // Determine the user offset (based on $_GET['p']) + $num_pages = ceil($num_users / 50); + + $p = (!isset($_GET['p']) || $_GET['p'] <= 1 || $_GET['p'] > $num_pages) ? 1 : intval($_GET['p']); + $start_from = 50 * ($p - 1); + + // Generate paging links + $paging_links = ''.$lang_common['Pages'].' '.paginate($num_pages, $p, 'admin_users.php?find_user=&'.implode('&', $query_str)); + + $page_title = array(pun_htmlspecialchars($pun_config['o_board_title']), $lang_admin_common['Admin'], $lang_admin_common['Users'], $lang_admin_users['Results head']); + define('PUN_ACTIVE_PAGE', 'admin'); + require PUN_ROOT.'header.php'; + +?> +
+
+ +
+ +
+
+
+
+ + +
+

+
+
+ + + + + + + + + + + + +query('SELECT u.id, u.username, u.email, u.title, u.num_posts, u.admin_note, g.g_id, g.g_user_title FROM '.$db->prefix.'users AS u LEFT JOIN '.$db->prefix.'groups AS g ON g.g_id=u.group_id WHERE u.id>1'.(!empty($conditions) ? ' AND '.implode(' AND ', $conditions) : '').' ORDER BY '.$db->escape($order_by).' '.$db->escape($direction).' LIMIT '.$start_from.', 50') or error('Unable to fetch user info', __FILE__, __LINE__, $db->error()); + if ($db->num_rows($result)) + { + while ($user_data = $db->fetch_assoc($result)) + { + $user_title = get_title($user_data); + + // This script is a special case in that we want to display "Not verified" for non-verified users + if (($user_data['g_id'] == '' || $user_data['g_id'] == PUN_UNVERIFIED) && $user_title != $lang_common['Banned']) + $user_title = ''.$lang_admin_users['Not verified'].''; + + $actions = ''.$lang_admin_users['Results view IP link'].' | '.$lang_admin_users['Results show posts link'].''; + +?> + + + + + + + + +'."\n"; + +?> + +
'.pun_htmlspecialchars($user_data['username']).'' ?>
'.$lang_admin_users['No match'].'
+
+
+
+ +
+
+
+ +
+ +
+
+
+ +
+

+
+
+

+
+
+ +
+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+     +
+ +
+
+
+
+

+
+
+ +

+
+
+
+
+ +
+ + + + + +
+
+
+
+
+
+
+
+
+ + +Order Allow,Deny +Deny from All + diff --git a/cache/index.html b/cache/index.html new file mode 100755 index 0000000..89337b2 --- /dev/null +++ b/cache/index.html @@ -0,0 +1 @@ +.. diff --git a/db_update.php b/db_update.php new file mode 100644 index 0000000..234ec87 --- /dev/null +++ b/db_update.php @@ -0,0 +1,1457 @@ +query('SELECT conf_value FROM '.$db->prefix.'config WHERE conf_name=\'o_cur_version\'') or error('Unable to fetch version info.', __FILE__, __LINE__, $db->error()); +$cur_version = $db->result($result); + +if (version_compare($cur_version, '1.2', '<')) + exit('Version mismatch. The database \''.$db_name.'\' doesn\'t seem to be running a FluxBB database schema supported by this update script.'); + +// Do some DB type specific checks +$mysql = false; +switch ($db_type) +{ + case 'mysql': + case 'mysqli': + case 'mysql_innodb': + case 'mysqli_innodb': + $mysql_info = $db->get_version(); + if (version_compare($mysql_info['version'], MIN_MYSQL_VERSION, '<')) + error('You are running MySQL version '.$mysql_version.'. FluxBB '.UPDATE_TO.' requires at least MySQL '.MIN_MYSQL_VERSION.' to run properly. You must upgrade your MySQL installation before you can continue.'); + + $mysql = true; + break; + + case 'pgsql': + $pgsql_info = $db->get_version(); + if (version_compare($pgsql_info['version'], MIN_PGSQL_VERSION, '<')) + error('You are running PostgreSQL version '.$pgsql_info.'. FluxBB '.UPDATE_TO.' requires at least PostgreSQL '.MIN_PGSQL_VERSION.' to run properly. You must upgrade your PostgreSQL installation before you can continue.'); + + break; +} + +// Get the forum config +$result = $db->query('SELECT * FROM '.$db->prefix.'config') or error('Unable to fetch config.', __FILE__, __LINE__, $db->error()); +while ($cur_config_item = $db->fetch_row($result)) + $pun_config[$cur_config_item[0]] = $cur_config_item[1]; + +// Check the database revision and the current version +if (isset($pun_config['o_database_revision']) && $pun_config['o_database_revision'] >= UPDATE_TO_DB_REVISION && + isset($pun_config['o_searchindex_revision']) && $pun_config['o_searchindex_revision'] >= UPDATE_TO_SI_REVISION && + isset($pun_config['o_parser_revision']) && $pun_config['o_parser_revision'] >= UPDATE_TO_PARSER_REVISION && + version_compare($pun_config['o_cur_version'], UPDATE_TO, '>=')) + exit('Your database is already as up-to-date as this script can make it.'); + +$default_style = $pun_config['o_default_style']; +if (!file_exists(PUN_ROOT.'style/'.$default_style.'.css')) + $default_style = 'Air'; + +// +// Determines whether $str is UTF-8 encoded or not +// +function seems_utf8($str) +{ + $str_len = strlen($str); + for ($i = 0; $i < $str_len; ++$i) + { + if (ord($str[$i]) < 0x80) continue; # 0bbbbbbb + else if ((ord($str[$i]) & 0xE0) == 0xC0) $n=1; # 110bbbbb + else if ((ord($str[$i]) & 0xF0) == 0xE0) $n=2; # 1110bbbb + else if ((ord($str[$i]) & 0xF8) == 0xF0) $n=3; # 11110bbb + else if ((ord($str[$i]) & 0xFC) == 0xF8) $n=4; # 111110bb + else if ((ord($str[$i]) & 0xFE) == 0xFC) $n=5; # 1111110b + else return false; # Does not match any model + + for ($j = 0; $j < $n; ++$j) # n bytes matching 10bbbbbb follow ? + { + if ((++$i == strlen($str)) || ((ord($str[$i]) & 0xC0) != 0x80)) + return false; + } + } + + return true; +} + + +// +// Translates the number from a HTML numeric entity into an UTF-8 character +// +function dcr2utf8($src) +{ + $dest = ''; + if ($src < 0) + return false; + else if ($src <= 0x007f) + $dest .= chr($src); + else if ($src <= 0x07ff) + { + $dest .= chr(0xc0 | ($src >> 6)); + $dest .= chr(0x80 | ($src & 0x003f)); + } + else if ($src == 0xFEFF) + { + // nop -- zap the BOM + } + else if ($src >= 0xD800 && $src <= 0xDFFF) + { + // found a surrogate + return false; + } + else if ($src <= 0xffff) + { + $dest .= chr(0xe0 | ($src >> 12)); + $dest .= chr(0x80 | (($src >> 6) & 0x003f)); + $dest .= chr(0x80 | ($src & 0x003f)); + } + else if ($src <= 0x10ffff) + { + $dest .= chr(0xf0 | ($src >> 18)); + $dest .= chr(0x80 | (($src >> 12) & 0x3f)); + $dest .= chr(0x80 | (($src >> 6) & 0x3f)); + $dest .= chr(0x80 | ($src & 0x3f)); + } + else + { + // out of range + return false; + } + + return $dest; +} + + +// +// Attempts to convert $str from $old_charset to UTF-8. Also converts HTML entities (including numeric entities) to UTF-8 characters +// +function convert_to_utf8(&$str, $old_charset) +{ + if ($str === null || $str == '') + return false; + + $save = $str; + + // Replace literal entities (for non-UTF-8 compliant html_entity_encode) + if (version_compare(PHP_VERSION, '5.0.0', '<') && $old_charset == 'ISO-8859-1' || $old_charset == 'ISO-8859-15') + $str = html_entity_decode($str, ENT_QUOTES, $old_charset); + + if ($old_charset != 'UTF-8' && !seems_utf8($str)) + { + if (function_exists('iconv')) + $str = iconv($old_charset == 'ISO-8859-1' ? 'WINDOWS-1252' : 'ISO-8859-1', 'UTF-8', $str); + else if (function_exists('mb_convert_encoding')) + $str = mb_convert_encoding($str, 'UTF-8', $old_charset == 'ISO-8859-1' ? 'WINDOWS-1252' : 'ISO-8859-1'); + else if ($old_charset == 'ISO-8859-1') + $str = utf8_encode($str); + } + + // Replace literal entities (for UTF-8 compliant html_entity_encode) + if (version_compare(PHP_VERSION, '5.0.0', '>=')) + $str = html_entity_decode($str, ENT_QUOTES, 'UTF-8'); + + // Replace numeric entities + $str = preg_replace_callback('/&#([0-9]+);/', 'utf8_callback_1', $str); + $str = preg_replace_callback('/&#x([a-f0-9]+);/i', 'utf8_callback_2', $str); + + // Remove "bad" characters + $str = remove_bad_characters($str); + + return ($save != $str); +} + + +function utf8_callback_1($matches) +{ + return dcr2utf8($matches[1]); +} + + +function utf8_callback_2($matches) +{ + return dcr2utf8(hexdec($matches[1])); +} + + +// +// Alter a table to be utf8. MySQL only +// Function based on update_convert_table_utf8() from the Drupal project (http://drupal.org/) +// +function alter_table_utf8($table) +{ + global $mysql, $db; + static $types; + + if (!$mysql) + return; + + if (!isset($types)) + { + $types = array( + 'char' => 'binary', + 'varchar' => 'varbinary', + 'tinytext' => 'tinyblob', + 'mediumtext' => 'mediumblob', + 'text' => 'blob', + 'longtext' => 'longblob' + ); + } + + // Set table default charset to utf8 + $db->query('ALTER TABLE '.$table.' CHARACTER SET utf8') or error('Unable to set table character set', __FILE__, __LINE__, $db->error()); + + // Find out which columns need converting and build SQL statements + $result = $db->query('SHOW FULL COLUMNS FROM '.$table) or error('Unable to fetch column information', __FILE__, __LINE__, $db->error()); + while ($cur_column = $db->fetch_assoc($result)) + { + if ($cur_column['Collation'] === null) + continue; + + list($type) = explode('(', $cur_column['Type']); + if (isset($types[$type]) && strpos($cur_column['Collation'], 'utf8') === false) + { + $allow_null = ($cur_column['Null'] == 'YES'); + $collate = (substr($cur_column['Collation'], -3) == 'bin') ? 'utf8_bin' : 'utf8_general_ci'; + + $db->alter_field($table, $cur_column['Field'], preg_replace('/'.$type.'/i', $types[$type], $cur_column['Type']), $allow_null, $cur_column['Default'], null, true) or error('Unable to alter field to binary', __FILE__, __LINE__, $db->error()); + $db->alter_field($table, $cur_column['Field'], $cur_column['Type'].' CHARACTER SET utf8 COLLATE '.$collate, $allow_null, $cur_column['Default'], null, true) or error('Unable to alter field to utf8', __FILE__, __LINE__, $db->error()); + } + } +} + +// +// Safely converts text type columns into utf8 +// If finished returns true, otherwise returns $end_at +// +function convert_table_utf8($table, $callback, $old_charset, $key = null, $start_at = null) +{ + global $mysql, $db; + + $finished = true; + $end_at = 0; + if ($mysql) + { + // Only set up the tables if we are doing this in 1 go, or its the first go + if ($start_at === null || $start_at == 0) + { + // Drop any temp table that exists, in-case it's left over from a failed update + $db->drop_table($table.'_utf8', true) or error('Unable to drop left over temp table', __FILE__, __LINE__, $db->error()); + + // Copy the table + $db->query('CREATE TABLE '.$table.'_utf8 LIKE '.$table) or error('Unable to create new table', __FILE__, __LINE__, $db->error()); + + // Set table default charset to utf8 + alter_table_utf8($table.'_utf8'); + } + + // Change to latin1 mode so MySQL doesn't attempt to perform conversion on the data from the old table + $db->set_names('latin1'); + + // Move & Convert everything + $result = $db->query('SELECT * FROM '.$table.($start_at === null ? '' : ' WHERE '.$key.'>'.$start_at).' ORDER BY '.$key.' ASC'.($start_at === null ? '' : ' LIMIT '.PER_PAGE), false) or error('Unable to select from old table', __FILE__, __LINE__, $db->error()); + + // Change back to utf8 mode so we can insert it into the new table + $db->set_names('utf8'); + + while ($cur_item = $db->fetch_assoc($result)) + { + $cur_item = call_user_func($callback, $cur_item, $old_charset); + + $temp = array(); + foreach ($cur_item as $idx => $value) + $temp[$idx] = $value === null ? 'NULL' : '\''.$db->escape($value).'\''; + + $db->query('INSERT INTO '.$table.'_utf8('.implode(',', array_keys($temp)).') VALUES ('.implode(',', array_values($temp)).')') or error('Unable to insert data to new table', __FILE__, __LINE__, $db->error()); + + $end_at = $cur_item[$key]; + } + + // If we aren't doing this all in 1 go and $end_at has a value (i.e. we have processed at least 1 row), figure out if we have more to do or not + if ($start_at !== null && $end_at > 0) + { + $result = $db->query('SELECT 1 FROM '.$table.' WHERE '.$key.'>'.$end_at.' ORDER BY '.$key.' ASC LIMIT 1') or error('Unable to check for next row', __FILE__, __LINE__, $db->error()); + $finished = $db->num_rows($result) == 0; + } + + // Only swap the tables if we are doing this in 1 go, or its the last go + if ($finished) + { + // Delete old table + $db->drop_table($table, true) or error('Unable to drop old table', __FILE__, __LINE__, $db->error()); + + // Rename table + $db->query('ALTER TABLE '.$table.'_utf8 RENAME '.$table) or error('Unable to rename new table', __FILE__, __LINE__, $db->error()); + + return true; + } + + return $end_at; + } + else + { + // Convert everything + $result = $db->query('SELECT * FROM '.$table.($start_at === null ? '' : ' WHERE '.$key.'>'.$start_at).' ORDER BY '.$key.' ASC'.($start_at === null ? '' : ' LIMIT '.PER_PAGE)) or error('Unable to select from table', __FILE__, __LINE__, $db->error()); + while ($cur_item = $db->fetch_assoc($result)) + { + $cur_item = call_user_func($callback, $cur_item, $old_charset); + + $temp = array(); + foreach ($cur_item as $idx => $value) + $temp[] = $idx.'='.($value === null ? 'NULL' : '\''.$db->escape($value).'\''); + + if (!empty($temp)) + $db->query('UPDATE '.$table.' SET '.implode(', ', $temp).' WHERE '.$key.'=\''.$db->escape($cur_item[$key]).'\'') or error('Unable to update data', __FILE__, __LINE__, $db->error()); + + $end_at = $cur_item[$key]; + } + + if ($start_at !== null && $end_at > 0) + { + $result = $db->query('SELECT 1 FROM '.$table.' WHERE '.$key.'>'.$end_at.' ORDER BY '.$key.' ASC LIMIT 1') or error('Unable to check for next row', __FILE__, __LINE__, $db->error()); + if ($db->num_rows($result) == 0) + return true; + + return $end_at; + } + + return true; + } +} + + +header('Content-type: text/html; charset=utf-8'); + +// Empty all output buffers and stop buffering +while (@ob_end_clean()); + + +$stage = isset($_GET['stage']) ? $_GET['stage'] : ''; +$old_charset = isset($_GET['req_old_charset']) ? str_replace('ISO8859', 'ISO-8859', strtoupper($_GET['req_old_charset'])) : 'ISO-8859-1'; +$start_at = isset($_GET['start_at']) ? intval($_GET['start_at']) : 0; +$query_str = ''; + +switch ($stage) +{ + // Show form + case '': + +?> + + + + + +FluxBB Database Update + + + + +
+
+
+ +
+

FluxBB Update

+
+
+ +
+
+

This script will update your forum database. The update procedure might take anything from a second to hours depending on the speed of the server and the size of the forum database. Don't forget to make a backup of the database before continuing.

+

Did you read the update instructions in the documentation? If not, start there.

+ +

IMPORTANT! FluxBB has detected that this PHP environment does not have support for the encoding mechanisms required to do UTF-8 conversion from character sets other than ISO-8859-1. What this means is that if the current character set is not ISO-8859-1, FluxBB won't be able to convert your forum database to UTF-8 and you will have to do it manually. Instructions for doing manual charset conversion can be found in the update instructions.

+ +
+
+
+
+

Enable conversion: When enabled this update script will, after it has made the required structural changes to the database, convert all text in the database from the current character set to UTF-8. This conversion is required if you're upgrading from version 1.2.

+

Current character set: If the primary language in your forum is English, you can leave this at the default value. However, if your forum is non-English, you should enter the character set of the primary language pack used in the forum. Getting this wrong can corrupt your database so don't just guess! Note: This is required even if the old database is UTF-8.

+
+
+ Charset conversion +
+
+ +
+ +
+
+'."\n"; + +?> +
+

+
+
+
+ +
+
+
+ + + += UPDATE_TO_DB_REVISION) + break; + + // Make all email fields VARCHAR(80) + $db->alter_field('bans', 'email', 'VARCHAR(80)', true) or error('Unable to alter email field', __FILE__, __LINE__, $db->error()); + $db->alter_field('posts', 'poster_email', 'VARCHAR(80)', true) or error('Unable to alter poster_email field', __FILE__, __LINE__, $db->error()); + $db->alter_field('users', 'email', 'VARCHAR(80)', false, '') or error('Unable to alter email field', __FILE__, __LINE__, $db->error()); + $db->alter_field('users', 'jabber', 'VARCHAR(80)', true) or error('Unable to alter jabber field', __FILE__, __LINE__, $db->error()); + $db->alter_field('users', 'msn', 'VARCHAR(80)', true) or error('Unable to alter msn field', __FILE__, __LINE__, $db->error()); + $db->alter_field('users', 'activate_string', 'VARCHAR(80)', true) or error('Unable to alter activate_string field', __FILE__, __LINE__, $db->error()); + + // Make all IP fields VARCHAR(39) to support IPv6 + $db->alter_field('posts', 'poster_ip', 'VARCHAR(39)', true) or error('Unable to alter poster_ip field', __FILE__, __LINE__, $db->error()); + $db->alter_field('users', 'registration_ip', 'VARCHAR(39)', false, '0.0.0.0') or error('Unable to alter registration_ip field', __FILE__, __LINE__, $db->error()); + + // Add the DST option to the users table + $db->add_field('users', 'dst', 'TINYINT(1)', false, 0, 'timezone') or error('Unable to add dst field', __FILE__, __LINE__, $db->error()); + + // Add the last_post field to the online table + $db->add_field('online', 'last_post', 'INT(10) UNSIGNED', true, null, null) or error('Unable to add last_post field', __FILE__, __LINE__, $db->error()); + + // Add the last_search field to the online table + $db->add_field('online', 'last_search', 'INT(10) UNSIGNED', true, null, null) or error('Unable to add last_search field', __FILE__, __LINE__, $db->error()); + + // Add the last_search column to the users table + $db->add_field('users', 'last_search', 'INT(10) UNSIGNED', true, null, 'last_post') or error('Unable to add last_search field', __FILE__, __LINE__, $db->error()); + + // Drop use_avatar column from users table + $db->drop_field('users', 'use_avatar') or error('Unable to drop use_avatar field', __FILE__, __LINE__, $db->error()); + + // Drop save_pass column from users table + $db->drop_field('users', 'save_pass') or error('Unable to drop save_pass field', __FILE__, __LINE__, $db->error()); + + // Drop g_edit_subjects_interval column from groups table + $db->drop_field('groups', 'g_edit_subjects_interval'); + + // Add database revision number + if (!array_key_exists('o_database_revision', $pun_config)) + $db->query('INSERT INTO '.$db->prefix.'config (conf_name, conf_value) VALUES (\'o_database_revision\', \'0\')') or error('Unable to insert config value \'o_database_revision\'', __FILE__, __LINE__, $db->error()); + + // Add search index revision number + if (!array_key_exists('o_searchindex_revision', $pun_config)) + $db->query('INSERT INTO '.$db->prefix.'config (conf_name, conf_value) VALUES (\'o_searchindex_revision\', \'0\')') or error('Unable to insert config value \'o_searchindex_revision\'', __FILE__, __LINE__, $db->error()); + + // Add parser revision number + if (!array_key_exists('o_parser_revision', $pun_config)) + $db->query('INSERT INTO '.$db->prefix.'config (conf_name, conf_value) VALUES (\'o_parser_revision\', \'0\')') or error('Unable to insert config value \'o_parser_revision\'', __FILE__, __LINE__, $db->error()); + + // Add default email setting option + if (!array_key_exists('o_default_email_setting', $pun_config)) + $db->query('INSERT INTO '.$db->prefix.'config (conf_name, conf_value) VALUES (\'o_default_email_setting\', \'1\')') or error('Unable to insert config value \'o_default_email_setting\'', __FILE__, __LINE__, $db->error()); + + // Make sure we have o_additional_navlinks (was added in 1.2.1) + if (!array_key_exists('o_additional_navlinks', $pun_config)) + $db->query('INSERT INTO '.$db->prefix.'config (conf_name, conf_value) VALUES (\'o_additional_navlinks\', \'\')') or error('Unable to insert config value \'o_additional_navlinks\'', __FILE__, __LINE__, $db->error()); + + // Insert new config option o_topic_views + if (!array_key_exists('o_topic_views', $pun_config)) + $db->query('INSERT INTO '.$db->prefix.'config (conf_name, conf_value) VALUES (\'o_topic_views\', \'1\')') or error('Unable to insert config value \'o_topic_views\'', __FILE__, __LINE__, $db->error()); + + // Insert new config option o_signatures + if (!array_key_exists('o_signatures', $pun_config)) + $db->query('INSERT INTO '.$db->prefix.'config (conf_name, conf_value) VALUES (\'o_signatures\', \'1\')') or error('Unable to insert config value \'o_signatures\'', __FILE__, __LINE__, $db->error()); + + // Insert new config option o_smtp_ssl + if (!array_key_exists('o_smtp_ssl', $pun_config)) + $db->query('INSERT INTO '.$db->prefix.'config (conf_name, conf_value) VALUES (\'o_smtp_ssl\', \'0\')') or error('Unable to insert config value \'o_smtp_ssl\'', __FILE__, __LINE__, $db->error()); + + // Insert new config option o_default_dst + if (!array_key_exists('o_default_dst', $pun_config)) + $db->query('INSERT INTO '.$db->prefix.'config (conf_name, conf_value) VALUES (\'o_default_dst\', \'0\')') or error('Unable to insert config value \'o_default_dst\'', __FILE__, __LINE__, $db->error()); + + // Insert new config option o_quote_depth + if (!array_key_exists('o_quote_depth', $pun_config)) + $db->query('INSERT INTO '.$db->prefix.'config (conf_name, conf_value) VALUES (\'o_quote_depth\', \'3\')') or error('Unable to insert config value \'o_quote_depth\'', __FILE__, __LINE__, $db->error()); + + // Insert new config option o_feed_type + if (!array_key_exists('o_feed_type', $pun_config)) + $db->query('INSERT INTO '.$db->prefix.'config (conf_name, conf_value) VALUES (\'o_feed_type\', \'2\')') or error('Unable to insert config value \'o_feed_type\'', __FILE__, __LINE__, $db->error()); + + // Insert config option o_base_url which was removed in 1.3 + if (!array_key_exists('o_base_url', $pun_config)) + { + // If it isn't in $pun_config['o_base_url'] it should be in $base_url, but just in-case it isn't we can make a guess at it + if (!isset($base_url)) + { + // Make an educated guess regarding base_url + $base_url = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') ? 'https://' : 'http://'; // protocol + $base_url .= preg_replace('/:(80|443)$/', '', $_SERVER['HTTP_HOST']); // host[:port] + $base_url .= str_replace('\\', '/', dirname($_SERVER['SCRIPT_NAME'])); // path + } + + if (substr($base_url, -1) == '/') + $base_url = substr($base_url, 0, -1); + + $db->query('INSERT INTO '.$db->prefix.'config (conf_name, conf_value) VALUES (\'o_base_url\', \''.$db->escape($base_url).'\')') or error('Unable to insert config value \'o_quote_depth\'', __FILE__, __LINE__, $db->error()); + } + + if (strpos($cur_version, '1.2') === 0) + { + // Groups are almost the same as 1.2: + // unverified: 32000 -> 0 + + $db->query('UPDATE '.$db->prefix.'users SET group_id = 0 WHERE group_id = 32000') or error('Unable to update unverified users', __FILE__, __LINE__, $db->error()); + } + else if (strpos($cur_version, '1.3') === 0) + { + // Groups have changed quite a lot from 1.3: + // unverified: 0 -> 0 + // admin: 1 -> 1 + // mod: ? -> 2 + // guest: 2 -> 3 + // member: ? -> 4 + + $result = $db->query('SELECT MAX(g_id) + 1 FROM '.$db->prefix.'groups') or error('Unable to select temp group ID', __FILE__, __LINE__, $db->error()); + $temp_id = $db->result($result); + + $result = $db->query('SELECT g_id FROM '.$db->prefix.'groups WHERE g_moderator = 1 AND g_id > 1 LIMIT 1') or error('Unable to select moderator group', __FILE__, __LINE__, $db->error()); + if ($db->num_rows($result)) + $mod_gid = $db->result($result); + else + { + $db->query('INSERT INTO '.$db->prefix.'groups (g_title, g_user_title, g_moderator, g_mod_edit_users, g_mod_rename_users, g_mod_change_passwords, g_mod_ban_users, g_read_board, g_view_users, g_post_replies, g_post_topics, g_edit_posts, g_delete_posts, g_delete_topics, g_set_title, g_search, g_search_users, g_send_email, g_post_flood, g_search_flood, g_email_flood) VALUES('."'Moderators', 'Moderator', 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0)") or error('Unable to add group', __FILE__, __LINE__, $db->error()); + $mod_gid = $db->insert_id(); + } + + $member_gid = $pun_config['o_default_user_group']; + + // move the mod group to a temp place + $db->query('UPDATE '.$db->prefix.'groups SET g_id = '.$temp_id.' WHERE g_id = '.$mod_gid) or error('Unable to update group ID', __FILE__, __LINE__, $db->error()); + $db->query('UPDATE '.$db->prefix.'users SET group_id = '.$temp_id.' WHERE group_id = '.$mod_gid) or error('Unable to update users group ID', __FILE__, __LINE__, $db->error()); + $db->query('UPDATE '.$db->prefix.'forum_perms SET group_id = '.$temp_id.' WHERE group_id = '.$mod_gid) or error('Unable to forum_perms group ID', __FILE__, __LINE__, $db->error()); + if ($member_gid == $mod_gid) $member_gid = $temp_id; + + // move whoever is in 3 to a spare slot + $db->query('UPDATE '.$db->prefix.'groups SET g_id = '.$mod_gid.' WHERE g_id = 3') or error('Unable to update group ID', __FILE__, __LINE__, $db->error()); + $db->query('UPDATE '.$db->prefix.'users SET group_id = '.$mod_gid.' WHERE group_id = 3') or error('Unable to update users group ID', __FILE__, __LINE__, $db->error()); + $db->query('UPDATE '.$db->prefix.'forum_perms SET group_id = '.$mod_gid.' WHERE group_id = 3') or error('Unable to forum_perms group ID', __FILE__, __LINE__, $db->error()); + if ($member_gid == 3) $member_gid = $mod_gid; + + // move guest to 3 + $db->query('UPDATE '.$db->prefix.'groups SET g_id = 3 WHERE g_id = 2') or error('Unable to update group ID', __FILE__, __LINE__, $db->error()); + $db->query('UPDATE '.$db->prefix.'users SET group_id = 3 WHERE group_id = 2') or error('Unable to update users group ID', __FILE__, __LINE__, $db->error()); + $db->query('UPDATE '.$db->prefix.'forum_perms SET group_id = 3 WHERE group_id = 2') or error('Unable to forum_perms group ID', __FILE__, __LINE__, $db->error()); + if ($member_gid == 2) $member_gid = 3; + + // move mod group in temp place to 2 + $db->query('UPDATE '.$db->prefix.'groups SET g_id = 2 WHERE g_id = '.$temp_id) or error('Unable to update group ID', __FILE__, __LINE__, $db->error()); + $db->query('UPDATE '.$db->prefix.'users SET group_id = 2 WHERE group_id = '.$temp_id) or error('Unable to update users group ID', __FILE__, __LINE__, $db->error()); + $db->query('UPDATE '.$db->prefix.'forum_perms SET group_id = 2 WHERE group_id = '.$temp_id) or error('Unable to forum_perms group ID', __FILE__, __LINE__, $db->error()); + if ($member_gid == $temp_id) $member_gid = 2; + + // Only move stuff around if it isn't already in the right place + if ($member_gid != $mod_gid || $member_gid != 4) + { + // move members to temp place + $db->query('UPDATE '.$db->prefix.'groups SET g_id = '.$temp_id.' WHERE g_id = '.$member_gid) or error('Unable to update group ID', __FILE__, __LINE__, $db->error()); + $db->query('UPDATE '.$db->prefix.'users SET group_id = '.$temp_id.' WHERE group_id = '.$member_gid) or error('Unable to update users group ID', __FILE__, __LINE__, $db->error()); + $db->query('UPDATE '.$db->prefix.'forum_perms SET group_id = '.$temp_id.' WHERE group_id = '.$member_gid) or error('Unable to forum_perms group ID', __FILE__, __LINE__, $db->error()); + + // move whoever is in 4 to members place + $db->query('UPDATE '.$db->prefix.'groups SET g_id = '.$member_gid.' WHERE g_id = 4') or error('Unable to update group ID', __FILE__, __LINE__, $db->error()); + $db->query('UPDATE '.$db->prefix.'users SET group_id = '.$member_gid.' WHERE group_id = 4') or error('Unable to update users group ID', __FILE__, __LINE__, $db->error()); + $db->query('UPDATE '.$db->prefix.'forum_perms SET group_id = '.$member_gid.' WHERE group_id = 4') or error('Unable to forum_perms group ID', __FILE__, __LINE__, $db->error()); + + // move members in temp place to 4 + $db->query('UPDATE '.$db->prefix.'groups SET g_id = 4 WHERE g_id = '.$temp_id) or error('Unable to update group ID', __FILE__, __LINE__, $db->error()); + $db->query('UPDATE '.$db->prefix.'users SET group_id = 4 WHERE group_id = '.$temp_id) or error('Unable to update users group ID', __FILE__, __LINE__, $db->error()); + $db->query('UPDATE '.$db->prefix.'forum_perms SET group_id = 4 WHERE group_id = '.$temp_id) or error('Unable to forum_perms group ID', __FILE__, __LINE__, $db->error()); + } + + $db->query('UPDATE '.$db->prefix.'config SET conf_value=\''.$member_gid.'\' WHERE conf_name=\'o_default_user_group\'') or error('Unable to update default user group ID', __FILE__, __LINE__, $db->error()); + } + + // Server time zone is now simply the default time zone + if (!array_key_exists('o_default_timezone', $pun_config)) + $db->query('UPDATE '.$db->prefix.'config SET conf_name = \'o_default_timezone\' WHERE conf_name = \'o_server_timezone\'') or error('Unable to update time zone config', __FILE__, __LINE__, $db->error()); + + // Increase visit timeout to 30 minutes (only if it hasn't been changed from the default) + if (!array_key_exists('o_database_revision', $pun_config) && $pun_config['o_timeout_visit'] == '600') + $db->query('UPDATE '.$db->prefix.'config SET conf_value = \'1800\' WHERE conf_name = \'o_timeout_visit\'') or error('Unable to update visit timeout config', __FILE__, __LINE__, $db->error()); + + // Remove obsolete g_post_polls permission from groups table + $db->drop_field('groups', 'g_post_polls'); + + // Make room for multiple moderator groups + if (!$db->field_exists('groups', 'g_moderator')) + { + // Add g_moderator column to groups table + $db->add_field('groups', 'g_moderator', 'TINYINT(1)', false, 0, 'g_user_title') or error('Unable to add g_moderator field', __FILE__, __LINE__, $db->error()); + + // Give the moderator group moderator privileges + $db->query('UPDATE '.$db->prefix.'groups SET g_moderator = 1 WHERE g_id = 2') or error('Unable to update moderator powers', __FILE__, __LINE__, $db->error()); + } + + // Replace obsolete p_mod_edit_users config setting with new per-group permission + if (array_key_exists('p_mod_edit_users', $pun_config)) + { + $db->query('DELETE FROM '.$db->prefix.'config WHERE conf_name = \'p_mod_edit_users\'') or error('Unable to update moderator powers', __FILE__, __LINE__, $db->error()); + + $db->add_field('groups', 'g_mod_edit_users', 'TINYINT(1)', false, 0, 'g_moderator') or error('Unable to add g_mod_edit_users field', __FILE__, __LINE__, $db->error()); + + $db->query('UPDATE '.$db->prefix.'groups SET g_mod_edit_users = '.$pun_config['p_mod_edit_users'].' WHERE g_moderator = 1') or error('Unable to update moderator powers', __FILE__, __LINE__, $db->error()); + } + + // Replace obsolete p_mod_rename_users config setting with new per-group permission + if (array_key_exists('p_mod_rename_users', $pun_config)) + { + $db->query('DELETE FROM '.$db->prefix.'config WHERE conf_name = \'p_mod_rename_users\'') or error('Unable to update moderator powers', __FILE__, __LINE__, $db->error()); + + $db->add_field('groups', 'g_mod_rename_users', 'TINYINT(1)', false, 0, 'g_mod_edit_users') or error('Unable to add g_mod_rename_users field', __FILE__, __LINE__, $db->error()); + + $db->query('UPDATE '.$db->prefix.'groups SET g_mod_rename_users = '.$pun_config['p_mod_rename_users'].' WHERE g_moderator = 1') or error('Unable to update moderator powers', __FILE__, __LINE__, $db->error()); + } + + // Replace obsolete p_mod_change_passwords config setting with new per-group permission + if (array_key_exists('p_mod_change_passwords', $pun_config)) + { + $db->query('DELETE FROM '.$db->prefix.'config WHERE conf_name = \'p_mod_change_passwords\'') or error('Unable to update moderator powers', __FILE__, __LINE__, $db->error()); + + $db->add_field('groups', 'g_mod_change_passwords', 'TINYINT(1)', false, 0, 'g_mod_rename_users') or error('Unable to add g_mod_change_passwords field', __FILE__, __LINE__, $db->error()); + + $db->query('UPDATE '.$db->prefix.'groups SET g_mod_change_passwords = '.$pun_config['p_mod_change_passwords'].' WHERE g_moderator = 1') or error('Unable to update moderator powers', __FILE__, __LINE__, $db->error()); + } + + // Replace obsolete p_mod_ban_users config setting with new per-group permission + if (array_key_exists('p_mod_ban_users', $pun_config)) + { + $db->query('DELETE FROM '.$db->prefix.'config WHERE conf_name = \'p_mod_ban_users\'') or error('Unable to update moderator powers', __FILE__, __LINE__, $db->error()); + + $db->add_field('groups', 'g_mod_ban_users', 'TINYINT(1)', false, 0, 'g_mod_change_passwords') or error('Unable to add g_mod_ban_users field', __FILE__, __LINE__, $db->error()); + + $db->query('UPDATE '.$db->prefix.'groups SET g_mod_ban_users = '.$pun_config['p_mod_ban_users'].' WHERE g_moderator = 1') or error('Unable to update moderator powers', __FILE__, __LINE__, $db->error()); + } + + // We need to add a unique index to avoid users having multiple rows in the online table + if (!$db->index_exists('online', 'user_id_ident_idx')) + { + $db->truncate_table('online') or error('Unable to clear online table', __FILE__, __LINE__, $db->error()); + + if ($mysql) + $db->add_index('online', 'user_id_ident_idx', array('user_id', 'ident(25)'), true) or error('Unable to add user_id_ident_idx index', __FILE__, __LINE__, $db->error()); + else + $db->add_index('online', 'user_id_ident_idx', array('user_id', 'ident'), true) or error('Unable to add user_id_ident_idx index', __FILE__, __LINE__, $db->error()); + } + + // Remove the redundant user_id_idx on the online table + $db->drop_index('online', 'user_id_idx') or error('Unable to drop user_id_idx index', __FILE__, __LINE__, $db->error()); + + // Add an index to ident on the online table + if ($mysql) + $db->add_index('online', 'ident_idx', array('ident(25)')) or error('Unable to add ident_idx index', __FILE__, __LINE__, $db->error()); + else + $db->add_index('online', 'ident_idx', array('ident')) or error('Unable to add ident_idx index', __FILE__, __LINE__, $db->error()); + + // Add an index to logged in the online table + $db->add_index('online', 'logged_idx', array('logged')) or error('Unable to add logged_idx index', __FILE__, __LINE__, $db->error()); + + // Add an index to last_post in the topics table + $db->add_index('topics', 'last_post_idx', array('last_post')) or error('Unable to add last_post_idx index', __FILE__, __LINE__, $db->error()); + + // Add an index to username on the bans table + if ($mysql) + $db->add_index('bans', 'username_idx', array('username(25)')) or error('Unable to add username_idx index', __FILE__, __LINE__, $db->error()); + else + $db->add_index('bans', 'username_idx', array('username')) or error('Unable to add username_idx index', __FILE__, __LINE__, $db->error()); + + // Change the username_idx on users to a unique index of max size 25 + $db->drop_index('users', 'username_idx') or error('Unable to drop old username_idx index', __FILE__, __LINE__, $db->error()); + $field = $mysql ? 'username(25)' : 'username'; + + // Attempt to add a unique index. If the user doesn't use a transactional database this can fail due to multiple matching usernames in the + // users table. This is bad, but just giving up if it happens is even worse! If it fails just add a regular non-unique index. + if (!$db->add_index('users', 'username_idx', array($field), true)) + $db->add_index('users', 'username_idx', array($field)) or error('Unable to add username_idx field', __FILE__, __LINE__, $db->error()); + + // Add g_view_users field to groups table + $db->add_field('groups', 'g_view_users', 'TINYINT(1)', false, 1, 'g_read_board') or error('Unable to add g_view_users field', __FILE__, __LINE__, $db->error()); + + // Add the last_email_sent column to the users table and the g_send_email and + // g_email_flood columns to the groups table + $db->add_field('users', 'last_email_sent', 'INT(10) UNSIGNED', true, null, 'last_search') or error('Unable to add last_email_sent field', __FILE__, __LINE__, $db->error()); + $db->add_field('groups', 'g_send_email', 'TINYINT(1)', false, 1, 'g_search_users') or error('Unable to add g_send_email field', __FILE__, __LINE__, $db->error()); + $db->add_field('groups', 'g_email_flood', 'SMALLINT(6)', false, 60, 'g_search_flood') or error('Unable to add g_email_flood field', __FILE__, __LINE__, $db->error()); + + // Set non-default g_send_email and g_flood_email values properly + $db->query('UPDATE '.$db->prefix.'groups SET g_send_email = 0 WHERE g_id = 3') or error('Unable to update group email permissions', __FILE__, __LINE__, $db->error()); + $db->query('UPDATE '.$db->prefix.'groups SET g_email_flood = 0 WHERE g_id IN (1,2,3)') or error('Unable to update group email permissions', __FILE__, __LINE__, $db->error()); + + // Add the auto notify/subscription option to the users table + $db->add_field('users', 'auto_notify', 'TINYINT(1)', false, 0, 'notify_with_post') or error('Unable to add auto_notify field', __FILE__, __LINE__, $db->error()); + + // Add the first_post_id column to the topics table + if (!$db->field_exists('topics', 'first_post_id')) + { + $db->add_field('topics', 'first_post_id', 'INT(10) UNSIGNED', false, 0, 'posted') or error('Unable to add first_post_id field', __FILE__, __LINE__, $db->error()); + $db->add_index('topics', 'first_post_id_idx', array('first_post_id')) or error('Unable to add first_post_id_idx index', __FILE__, __LINE__, $db->error()); + + // Now that we've added the column and indexed it, we need to give it correct data + $result = $db->query('SELECT MIN(id) AS first_post, topic_id FROM '.$db->prefix.'posts GROUP BY topic_id') or error('Unable to fetch first_post_id', __FILE__, __LINE__, $db->error()); + + while ($cur_post = $db->fetch_assoc($result)) + $db->query('UPDATE '.$db->prefix.'topics SET first_post_id = '.$cur_post['first_post'].' WHERE id = '.$cur_post['topic_id']) or error('Unable to update first_post_id', __FILE__, __LINE__, $db->error()); + } + + // Move any users with the old unverified status to their new group + $db->query('UPDATE '.$db->prefix.'users SET group_id=0 WHERE group_id=32000') or error('Unable to move unverified users', __FILE__, __LINE__, $db->error()); + + // Add the ban_creator column to the bans table + $db->add_field('bans', 'ban_creator', 'INT(10) UNSIGNED', false, 0) or error('Unable to add ban_creator field', __FILE__, __LINE__, $db->error()); + + // Add the time/date format settings to the user table + $db->add_field('users', 'time_format', 'TINYINT(1)', false, 0, 'dst') or error('Unable to add time_format field', __FILE__, __LINE__, $db->error()); + $db->add_field('users', 'date_format', 'TINYINT(1)', false, 0, 'dst') or error('Unable to add date_format field', __FILE__, __LINE__, $db->error()); + + // Change the search_data field to mediumtext + $db->alter_field('search_cache', 'search_data', 'MEDIUMTEXT', true) or error('Unable to alter search_data field', __FILE__, __LINE__, $db->error()); + + // Incase we had the fulltext search extension installed (1.3-legacy), remove it + $db->drop_index('topics', 'subject_idx') or error('Unable to drop subject_idx index', __FILE__, __LINE__, $db->error()); + $db->drop_index('posts', 'message_idx') or error('Unable to drop message_idx index', __FILE__, __LINE__, $db->error()); + + // If the search_cache table has been dropped by the fulltext search extension, recreate it + if (!$db->table_exists('search_cache')) + { + $schema = array( + 'FIELDS' => array( + 'id' => array( + 'datatype' => 'INT(10) UNSIGNED', + 'allow_null' => false, + 'default' => '0' + ), + 'ident' => array( + 'datatype' => 'VARCHAR(200)', + 'allow_null' => false, + 'default' => '\'\'' + ), + 'search_data' => array( + 'datatype' => 'MEDIUMTEXT', + 'allow_null' => true + ) + ), + 'PRIMARY KEY' => array('id'), + 'INDEXES' => array( + 'ident_idx' => array('ident') + ) + ); + + if ($db_type == 'mysql' || $db_type == 'mysqli' || $db_type == 'mysql_innodb' || $db_type == 'mysqli_innodb') + $schema['INDEXES']['ident_idx'] = array('ident(8)'); + + $db->create_table('search_cache', $schema); + } + + // If the search_matches table has been dropped by the fulltext search extension, recreate it + if (!$db->table_exists('search_matches')) + { + $schema = array( + 'FIELDS' => array( + 'post_id' => array( + 'datatype' => 'INT(10) UNSIGNED', + 'allow_null' => false, + 'default' => '0' + ), + 'word_id' => array( + 'datatype' => 'INT(10) UNSIGNED', + 'allow_null' => false, + 'default' => '0' + ), + 'subject_match' => array( + 'datatype' => 'TINYINT(1)', + 'allow_null' => false, + 'default' => '0' + ) + ), + 'INDEXES' => array( + 'word_id_idx' => array('word_id'), + 'post_id_idx' => array('post_id') + ) + ); + + $db->create_table('search_matches', $schema); + } + + // If the search_words table has been dropped by the fulltext search extension, recreate it + if (!$db->table_exists('search_words')) + { + $schema = array( + 'FIELDS' => array( + 'id' => array( + 'datatype' => 'SERIAL', + 'allow_null' => false + ), + 'word' => array( + 'datatype' => 'VARCHAR(20)', + 'allow_null' => false, + 'default' => '\'\'', + 'collation' => 'bin' + ) + ), + 'PRIMARY KEY' => array('word'), + 'INDEXES' => array( + 'id_idx' => array('id') + ) + ); + + if ($db_type == 'sqlite') + { + $schema['PRIMARY KEY'] = array('id'); + $schema['UNIQUE KEYS'] = array('word_idx' => array('word')); + } + + $db->create_table('search_words', $schema); + } + + // Change the default style if the old doesn't exist anymore + if ($pun_config['o_default_style'] != $default_style) + $db->query('UPDATE '.$db->prefix.'config SET conf_value = \''.$db->escape($default_style).'\' WHERE conf_name = \'o_default_style\'') or error('Unable to update default style config', __FILE__, __LINE__, $db->error()); + + // Should we do charset conversion or not? + if (strpos($cur_version, '1.2') === 0 && isset($_GET['convert_charset'])) + $query_str = '?stage=conv_bans&req_old_charset='.$old_charset; + + break; + + + // Convert bans + case 'conv_bans': + $query_str = '?stage=conv_categories&req_old_charset='.$old_charset; + + function _conv_bans($cur_item, $old_charset) + { + echo 'Converting ban '.$cur_item['id'].' …
'."\n"; + + convert_to_utf8($cur_item['username'], $old_charset); + convert_to_utf8($cur_item['message'], $old_charset); + + return $cur_item; + } + + $end_at = convert_table_utf8($db->prefix.'bans', '_conv_bans', $old_charset, 'id', $start_at); + + if ($end_at !== true) + $query_str = '?stage=conv_bans&req_old_charset='.$old_charset.'&start_at='.$end_at; + + break; + + + // Convert categories + case 'conv_categories': + $query_str = '?stage=conv_censors&req_old_charset='.$old_charset; + + echo 'Converting categories …'."
\n"; + + function _conv_categories($cur_item, $old_charset) + { + convert_to_utf8($cur_item['cat_name'], $old_charset); + + return $cur_item; + } + + convert_table_utf8($db->prefix.'categories', '_conv_categories', $old_charset, 'id'); + + break; + + + // Convert censor words + case 'conv_censors': + $query_str = '?stage=conv_config&req_old_charset='.$old_charset; + + echo 'Converting censor words …'."
\n"; + + function _conv_censoring($cur_item, $old_charset) + { + convert_to_utf8($cur_item['search_for'], $old_charset); + convert_to_utf8($cur_item['replace_with'], $old_charset); + + return $cur_item; + } + + convert_table_utf8($db->prefix.'censoring', '_conv_censoring', $old_charset, 'id'); + + break; + + + // Convert config + case 'conv_config': + $query_str = '?stage=conv_forums&req_old_charset='.$old_charset; + + echo 'Converting configuration …'."
\n"; + + function _conv_config($cur_item, $old_charset) + { + convert_to_utf8($cur_item['conf_value'], $old_charset); + + return $cur_item; + } + + convert_table_utf8($db->prefix.'config', '_conv_config', $old_charset, 'conf_name'); + + break; + + + // Convert forums + case 'conv_forums': + $query_str = '?stage=conv_perms&req_old_charset='.$old_charset; + + echo 'Converting forums …'."
\n"; + + function _conv_forums($cur_item, $old_charset) + { + $moderators = ($cur_item['moderators'] != '') ? unserialize($cur_item['moderators']) : array(); + $moderators_utf8 = array(); + foreach ($moderators as $mod_username => $mod_user_id) + { + convert_to_utf8($mod_username, $old_charset); + $moderators_utf8[$mod_username] = $mod_user_id; + } + + convert_to_utf8($cur_item['forum_name'], $old_charset); + convert_to_utf8($cur_item['forum_desc'], $old_charset); + + if (!empty($moderators_utf8)) + $cur_item['moderators'] = serialize($moderators_utf8); + + return $cur_item; + } + + convert_table_utf8($db->prefix.'forums', '_conv_forums', $old_charset, 'id'); + + break; + + + // Convert forum permissions + case 'conv_perms': + $query_str = '?stage=conv_groups&req_old_charset='.$old_charset; + + alter_table_utf8($db->prefix.'forum_perms'); + + break; + + + // Convert groups + case 'conv_groups': + $query_str = '?stage=conv_online&req_old_charset='.$old_charset; + + echo 'Converting groups …'."
\n"; + + function _conv_groups($cur_item, $old_charset) + { + convert_to_utf8($cur_item['g_title'], $old_charset); + convert_to_utf8($cur_item['g_user_title'], $old_charset); + + return $cur_item; + } + + convert_table_utf8($db->prefix.'groups', '_conv_groups', $old_charset, 'g_id'); + + break; + + + // Convert online + case 'conv_online': + $query_str = '?stage=conv_posts&req_old_charset='.$old_charset; + + // Truncate the table + $db->truncate_table('online') or error('Unable to empty online table', __FILE__, __LINE__, $db->error()); + + alter_table_utf8($db->prefix.'online'); + + break; + + + // Convert posts + case 'conv_posts': + $query_str = '?stage=conv_ranks&req_old_charset='.$old_charset; + + function _conv_posts($cur_item, $old_charset) + { + echo 'Converting post '.$cur_item['id'].' …
'."\n"; + + convert_to_utf8($cur_item['poster'], $old_charset); + convert_to_utf8($cur_item['message'], $old_charset); + convert_to_utf8($cur_item['edited_by'], $old_charset); + + return $cur_item; + } + + $end_at = convert_table_utf8($db->prefix.'posts', '_conv_posts', $old_charset, 'id', $start_at); + + if ($end_at !== true) + $query_str = '?stage=conv_posts&req_old_charset='.$old_charset.'&start_at='.$end_at; + + break; + + + // Convert ranks + case 'conv_ranks': + $query_str = '?stage=conv_reports&req_old_charset='.$old_charset; + + echo 'Converting ranks …'."
\n"; + + function _conv_ranks($cur_item, $old_charset) + { + convert_to_utf8($cur_item['rank'], $old_charset); + + return $cur_item; + } + + convert_table_utf8($db->prefix.'ranks', '_conv_ranks', $old_charset, 'id'); + + break; + + + // Convert reports + case 'conv_reports': + $query_str = '?stage=conv_search_cache&req_old_charset='.$old_charset; + + function _conv_reports($cur_item, $old_charset) + { + echo 'Converting report '.$cur_item['id'].' …
'."\n"; + + convert_to_utf8($cur_item['message'], $old_charset); + + return $cur_item; + } + + $end_at = convert_table_utf8($db->prefix.'reports', '_conv_reports', $old_charset, 'id', $start_at); + + if ($end_at !== true) + $query_str = '?stage=conv_reports&req_old_charset='.$old_charset.'&start_at='.$end_at; + + break; + + + // Convert search cache + case 'conv_search_cache': + $query_str = '?stage=conv_search_matches&req_old_charset='.$old_charset; + + // Truncate the table + $db->truncate_table('search_cache') or error('Unable to empty search cache table', __FILE__, __LINE__, $db->error()); + + alter_table_utf8($db->prefix.'search_cache'); + + break; + + + // Convert search matches + case 'conv_search_matches': + $query_str = '?stage=conv_search_words&req_old_charset='.$old_charset; + + // Truncate the table + $db->truncate_table('search_matches') or error('Unable to empty search index match table', __FILE__, __LINE__, $db->error()); + + alter_table_utf8($db->prefix.'search_matches'); + + break; + + + // Convert search words + case 'conv_search_words': + $query_str = '?stage=conv_subscriptions&req_old_charset='.$old_charset; + + // Truncate the table + $db->truncate_table('search_words') or error('Unable to empty search index words table', __FILE__, __LINE__, $db->error()); + + // Reset the sequence for the search words (not needed for SQLite) + switch ($db_type) + { + case 'mysql': + case 'mysqli': + case 'mysql_innodb': + case 'mysqli_innodb': + $db->query('ALTER TABLE '.$db->prefix.'search_words auto_increment=1') or error('Unable to update table auto_increment', __FILE__, __LINE__, $db->error()); + break; + + case 'pgsql'; + $db->query('SELECT setval(\''.$db->prefix.'search_words_id_seq\', 1, false)') or error('Unable to update sequence', __FILE__, __LINE__, $db->error()); + break; + } + + alter_table_utf8($db->prefix.'search_words'); + + break; + + + // Convert subscriptions + case 'conv_subscriptions': + $query_str = '?stage=conv_topics&req_old_charset='.$old_charset; + + alter_table_utf8($db->prefix.'subscriptions'); + + break; + + + // Convert topics + case 'conv_topics': + $query_str = '?stage=conv_users&req_old_charset='.$old_charset; + + function _conv_topics($cur_item, $old_charset) + { + echo 'Converting topic '.$cur_item['id'].' …
'."\n"; + + convert_to_utf8($cur_item['poster'], $old_charset); + convert_to_utf8($cur_item['subject'], $old_charset); + convert_to_utf8($cur_item['last_poster'], $old_charset); + + return $cur_item; + } + + $end_at = convert_table_utf8($db->prefix.'topics', '_conv_topics', $old_charset, 'id', $start_at); + + if ($end_at !== true) + $query_str = '?stage=conv_topics&req_old_charset='.$old_charset.'&start_at='.$end_at; + + break; + + + // Convert users + case 'conv_users': + $query_str = '?stage=preparse_posts'; + + function _conv_users($cur_item, $old_charset) + { + echo 'Converting user '.$cur_item['id'].' …
'."\n"; + + convert_to_utf8($cur_item['username'], $old_charset); + convert_to_utf8($cur_item['title'], $old_charset); + convert_to_utf8($cur_item['realname'], $old_charset); + convert_to_utf8($cur_item['location'], $old_charset); + convert_to_utf8($cur_item['signature'], $old_charset); + convert_to_utf8($cur_item['admin_note'], $old_charset); + + return $cur_item; + } + + $end_at = convert_table_utf8($db->prefix.'users', '_conv_users', $old_charset, 'id', $start_at); + + if ($end_at !== true) + $query_str = '?stage=conv_users&req_old_charset='.$old_charset.'&start_at='.$end_at; + + break; + + + // Preparse posts + case 'preparse_posts': + $query_str = '?stage=preparse_sigs'; + + // If we don't need to parse the posts, skip this stage + if (isset($pun_config['o_parser_revision']) && $pun_config['o_parser_revision'] >= UPDATE_TO_PARSER_REVISION) + break; + + require PUN_ROOT.'include/parser.php'; + + // Fetch posts to process this cycle + $result = $db->query('SELECT id, message FROM '.$db->prefix.'posts WHERE id > '.$start_at.' ORDER BY id ASC LIMIT '.PER_PAGE) or error('Unable to fetch posts', __FILE__, __LINE__, $db->error()); + + $temp = array(); + $end_at = 0; + while ($cur_item = $db->fetch_assoc($result)) + { + echo 'Preparsing post '.$cur_item['id'].' …
'."\n"; + $db->query('UPDATE '.$db->prefix.'posts SET message = \''.$db->escape(preparse_bbcode($cur_item['message'], $temp)).'\' WHERE id = '.$cur_item['id']) or error('Unable to update post', __FILE__, __LINE__, $db->error()); + + $end_at = $cur_item['id']; + } + + // Check if there is more work to do + if ($end_at > 0) + { + $result = $db->query('SELECT 1 FROM '.$db->prefix.'posts WHERE id > '.$end_at.' ORDER BY id ASC LIMIT 1') or error('Unable to fetch next ID', __FILE__, __LINE__, $db->error()); + + if ($db->num_rows($result) > 0) + $query_str = '?stage=preparse_posts&start_at='.$end_at; + } + + break; + + + // Preparse signatures + case 'preparse_sigs': + $query_str = '?stage=rebuild_idx'; + + // If we don't need to parse the sigs, skip this stage + if (isset($pun_config['o_parser_revision']) && $pun_config['o_parser_revision'] >= UPDATE_TO_PARSER_REVISION) + break; + + require PUN_ROOT.'include/parser.php'; + + // Fetch users to process this cycle + $result = $db->query('SELECT id, signature FROM '.$db->prefix.'users WHERE id > '.$start_at.' ORDER BY id ASC LIMIT '.PER_PAGE) or error('Unable to fetch users', __FILE__, __LINE__, $db->error()); + + $temp = array(); + $end_at = 0; + while ($cur_item = $db->fetch_assoc($result)) + { + echo 'Preparsing signature '.$cur_item['id'].' …
'."\n"; + $db->query('UPDATE '.$db->prefix.'users SET signature = \''.$db->escape(preparse_bbcode($cur_item['signature'], $temp, true)).'\' WHERE id = '.$cur_item['id']) or error('Unable to update user', __FILE__, __LINE__, $db->error()); + + $end_at = $cur_item['id']; + } + + // Check if there is more work to do + if ($end_at > 0) + { + $result = $db->query('SELECT 1 FROM '.$db->prefix.'users WHERE id > '.$end_at.' ORDER BY id ASC LIMIT 1') or error('Unable to fetch next ID', __FILE__, __LINE__, $db->error()); + if ($db->num_rows($result) > 0) + $query_str = '?stage=preparse_sigs&start_at='.$end_at; + } + + break; + + + // Rebuild the search index + case 'rebuild_idx': + $query_str = '?stage=finish'; + + // If we don't need to update the search index, skip this stage + if (isset($pun_config['o_searchindex_revision']) && $pun_config['o_searchindex_revision'] >= UPDATE_TO_SI_REVISION) + break; + + if ($start_at == 0) + { + // Truncate the tables just in-case we didn't already (if we are coming directly here without converting the tables) + $db->truncate_table('search_cache') or error('Unable to empty search cache table', __FILE__, __LINE__, $db->error()); + $db->truncate_table('search_matches') or error('Unable to empty search index match table', __FILE__, __LINE__, $db->error()); + $db->truncate_table('search_words') or error('Unable to empty search index words table', __FILE__, __LINE__, $db->error()); + + // Reset the sequence for the search words (not needed for SQLite) + switch ($db_type) + { + case 'mysql': + case 'mysqli': + case 'mysql_innodb': + case 'mysqli_innodb': + $db->query('ALTER TABLE '.$db->prefix.'search_words auto_increment=1') or error('Unable to update table auto_increment', __FILE__, __LINE__, $db->error()); + break; + + case 'pgsql'; + $db->query('SELECT setval(\''.$db->prefix.'search_words_id_seq\', 1, false)') or error('Unable to update sequence', __FILE__, __LINE__, $db->error()); + break; + } + } + + require PUN_ROOT.'include/search_idx.php'; + + // Fetch posts to process this cycle + $result = $db->query('SELECT p.id, p.message, t.subject, t.first_post_id FROM '.$db->prefix.'posts AS p INNER JOIN '.$db->prefix.'topics AS t ON t.id=p.topic_id WHERE p.id > '.$start_at.' ORDER BY p.id ASC LIMIT '.PER_PAGE) or error('Unable to fetch posts', __FILE__, __LINE__, $db->error()); + + $end_at = 0; + while ($cur_item = $db->fetch_assoc($result)) + { + echo 'Rebuilding index for post '.$cur_item['id'].' …
'."\n"; + + if ($cur_item['id'] == $cur_item['first_post_id']) + update_search_index('post', $cur_item['id'], $cur_item['message'], $cur_item['subject']); + else + update_search_index('post', $cur_item['id'], $cur_item['message']); + + $end_at = $cur_item['id']; + } + + // Check if there is more work to do + if ($end_at > 0) + { + $result = $db->query('SELECT 1 FROM '.$db->prefix.'posts WHERE id > '.$end_at.' ORDER BY id ASC LIMIT 1') or error('Unable to fetch next ID', __FILE__, __LINE__, $db->error()); + + if ($db->num_rows($result) > 0) + $query_str = '?stage=rebuild_idx&start_at='.$end_at; + } + + break; + + + // Show results page + case 'finish': + // We update the version number + $db->query('UPDATE '.$db->prefix.'config SET conf_value = \''.UPDATE_TO.'\' WHERE conf_name = \'o_cur_version\'') or error('Unable to update version', __FILE__, __LINE__, $db->error()); + + // And the database revision number + $db->query('UPDATE '.$db->prefix.'config SET conf_value = \''.UPDATE_TO_DB_REVISION.'\' WHERE conf_name = \'o_database_revision\'') or error('Unable to update database revision number', __FILE__, __LINE__, $db->error()); + + // And the search index revision number + $db->query('UPDATE '.$db->prefix.'config SET conf_value = \''.UPDATE_TO_SI_REVISION.'\' WHERE conf_name = \'o_searchindex_revision\'') or error('Unable to update search index revision number', __FILE__, __LINE__, $db->error()); + + // And the parser revision number + $db->query('UPDATE '.$db->prefix.'config SET conf_value = \''.UPDATE_TO_PARSER_REVISION.'\' WHERE conf_name = \'o_parser_revision\'') or error('Unable to update parser revision number', __FILE__, __LINE__, $db->error()); + + // This feels like a good time to synchronize the forums + $result = $db->query('SELECT id FROM '.$db->prefix.'forums') or error('Unable to fetch forum IDs', __FILE__, __LINE__, $db->error()); + + while ($row = $db->fetch_row($result)) + update_forum($row[0]); + + // Empty the PHP cache + forum_clear_cache(); + +?> + + + + + +FluxBB Database Update + + + + +
+
+
+ +
+

FluxBB Update

+
+
+
+
+

Your forum database was successfully updated. You may now go to the forum index.

+
+
+
+
+
+ +
+
+
+ + + +end_transaction(); +$db->close(); + +if ($query_str != '') + exit('
JavaScript seems to be disabled. Click here to continue.'); diff --git a/delete.php b/delete.php new file mode 100644 index 0000000..ebeda07 --- /dev/null +++ b/delete.php @@ -0,0 +1,133 @@ +query('SELECT f.id AS fid, f.forum_name, f.moderators, f.redirect_url, fp.post_replies, fp.post_topics, t.id AS tid, t.subject, t.posted, t.first_post_id, t.closed, p.poster, p.poster_id, p.message, p.hide_smilies FROM '.$db->prefix.'posts AS p INNER JOIN '.$db->prefix.'topics AS t ON t.id=p.topic_id INNER JOIN '.$db->prefix.'forums AS f ON f.id=t.forum_id LEFT JOIN '.$db->prefix.'forum_perms AS fp ON (fp.forum_id=f.id AND fp.group_id='.$pun_user['g_id'].') WHERE (fp.read_forum IS NULL OR fp.read_forum=1) AND p.id='.$id) or error('Unable to fetch post info', __FILE__, __LINE__, $db->error()); +if (!$db->num_rows($result)) + message($lang_common['Bad request']); + +$cur_post = $db->fetch_assoc($result); + +if ($pun_config['o_censoring'] == '1') + $cur_post['subject'] = censor_words($cur_post['subject']); + +// Sort out who the moderators are and if we are currently a moderator (or an admin) +$mods_array = ($cur_post['moderators'] != '') ? unserialize($cur_post['moderators']) : array(); +$is_admmod = ($pun_user['g_id'] == PUN_ADMIN || ($pun_user['g_moderator'] == '1' && array_key_exists($pun_user['username'], $mods_array))) ? true : false; + +$is_topic_post = ($id == $cur_post['first_post_id']) ? true : false; + +// Do we have permission to edit this post? +if (($pun_user['g_delete_posts'] == '0' || + ($pun_user['g_delete_topics'] == '0' && $is_topic_post) || + $cur_post['poster_id'] != $pun_user['id'] || + $cur_post['closed'] == '1') && + !$is_admmod) + message($lang_common['No permission']); + +// Load the delete.php language file +require PUN_ROOT.'lang/'.$pun_user['language'].'/delete.php'; + + +if (isset($_POST['delete'])) +{ + if ($is_admmod) + confirm_referrer('delete.php'); + + require PUN_ROOT.'include/search_idx.php'; + + if ($is_topic_post) + { + // Delete the topic and all of it's posts + delete_topic($cur_post['tid']); + update_forum($cur_post['fid']); + + redirect('viewforum.php?id='.$cur_post['fid'], $lang_delete['Topic del redirect']); + } + else + { + // Delete just this one post + delete_post($id, $cur_post['tid']); + update_forum($cur_post['fid']); + + redirect('viewtopic.php?id='.$cur_post['tid'], $lang_delete['Post del redirect']); + } +} + + +$page_title = array(pun_htmlspecialchars($pun_config['o_board_title']), $lang_delete['Delete post']); +define ('PUN_ACTIVE_PAGE', 'index'); +require PUN_ROOT.'header.php'; + +require PUN_ROOT.'include/parser.php'; +$cur_post['message'] = parse_message($cur_post['message'], $cur_post['hide_smilies']); + +?> +
+
+ +
+
+ +
+

+
+
+
+
+

'.pun_htmlspecialchars($cur_post['poster']).'', format_time($cur_post['posted'])) ?>

+

'.$lang_delete['Topic warning'].'' : ''.$lang_delete['Warning'].'' ?>

+
+
+

+
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+
+
+
+
+
+
+query('SELECT f.id AS fid, f.forum_name, f.moderators, f.redirect_url, fp.post_replies, fp.post_topics, t.id AS tid, t.subject, t.posted, t.first_post_id, t.closed, p.poster, p.poster_id, p.message, p.hide_smilies FROM '.$db->prefix.'posts AS p INNER JOIN '.$db->prefix.'topics AS t ON t.id=p.topic_id INNER JOIN '.$db->prefix.'forums AS f ON f.id=t.forum_id LEFT JOIN '.$db->prefix.'forum_perms AS fp ON (fp.forum_id=f.id AND fp.group_id='.$pun_user['g_id'].') WHERE (fp.read_forum IS NULL OR fp.read_forum=1) AND p.id='.$id) or error('Unable to fetch post info', __FILE__, __LINE__, $db->error()); +if (!$db->num_rows($result)) + message($lang_common['Bad request']); + +$cur_post = $db->fetch_assoc($result); + +// Sort out who the moderators are and if we are currently a moderator (or an admin) +$mods_array = ($cur_post['moderators'] != '') ? unserialize($cur_post['moderators']) : array(); +$is_admmod = ($pun_user['g_id'] == PUN_ADMIN || ($pun_user['g_moderator'] == '1' && array_key_exists($pun_user['username'], $mods_array))) ? true : false; + +$can_edit_subject = $id == $cur_post['first_post_id']; + +if ($pun_config['o_censoring'] == '1') +{ + $cur_post['subject'] = censor_words($cur_post['subject']); + $cur_post['message'] = censor_words($cur_post['message']); +} + +// Do we have permission to edit this post? +if (($pun_user['g_edit_posts'] == '0' || + $cur_post['poster_id'] != $pun_user['id'] || + $cur_post['closed'] == '1') && + !$is_admmod) + message($lang_common['No permission']); + +// Load the post.php/edit.php language file +require PUN_ROOT.'lang/'.$pun_user['language'].'/post.php'; + +// Start with a clean slate +$errors = array(); + + +if (isset($_POST['form_sent'])) +{ + if ($is_admmod) + confirm_referrer('edit.php'); + + // If it's a topic it must contain a subject + if ($can_edit_subject) + { + $subject = pun_trim($_POST['req_subject']); + + if ($subject == '') + $errors[] = $lang_post['No subject']; + else if (pun_strlen($subject) > 70) + $errors[] = $lang_post['Too long subject']; + else if ($pun_config['p_subject_all_caps'] == '0' && is_all_uppercase($subject) && !$pun_user['is_admmod']) + $errors[] = $lang_post['All caps subject']; + } + + // Clean up message from POST + $message = pun_linebreaks(pun_trim($_POST['req_message'])); + + if (pun_strlen($message) > PUN_MAX_POSTSIZE) + $errors[] = $lang_post['Too long message']; + else if ($pun_config['p_message_all_caps'] == '0' && is_all_uppercase($message) && !$pun_user['is_admmod']) + $errors[] = $lang_post['All caps message']; + + // Validate BBCode syntax + if ($pun_config['p_message_bbcode'] == '1') + { + require PUN_ROOT.'include/parser.php'; + $message = preparse_bbcode($message, $errors); + } + + if ($message == '') + $errors[] = $lang_post['No message']; + + $hide_smilies = isset($_POST['hide_smilies']) ? '1' : '0'; + + // Did everything go according to plan? + if (empty($errors) && !isset($_POST['preview'])) + { + $edited_sql = (!isset($_POST['silent']) || !$is_admmod) ? $edited_sql = ', edited='.time().', edited_by=\''.$db->escape($pun_user['username']).'\'' : ''; + + require PUN_ROOT.'include/search_idx.php'; + + if ($can_edit_subject) + { + // Update the topic and any redirect topics + $db->query('UPDATE '.$db->prefix.'topics SET subject=\''.$db->escape($subject).'\' WHERE id='.$cur_post['tid'].' OR moved_to='.$cur_post['tid']) or error('Unable to update topic', __FILE__, __LINE__, $db->error()); + + // We changed the subject, so we need to take that into account when we update the search words + update_search_index('edit', $id, $message, $subject); + } + else + update_search_index('edit', $id, $message); + + // Update the post + $db->query('UPDATE '.$db->prefix.'posts SET message=\''.$db->escape($message).'\', hide_smilies='.$hide_smilies.$edited_sql.' WHERE id='.$id) or error('Unable to update post', __FILE__, __LINE__, $db->error()); + + redirect('viewtopic.php?pid='.$id.'#p'.$id, $lang_post['Edit redirect']); + } +} + + + +$page_title = array(pun_htmlspecialchars($pun_config['o_board_title']), $lang_post['Edit post']); +$required_fields = array('req_subject' => $lang_common['Subject'], 'req_message' => $lang_common['Message']); +$focus_element = array('edit', 'req_message'); +define('PUN_ACTIVE_PAGE', 'index'); +require PUN_ROOT.'header.php'; + +$cur_index = 1; + +?> +
+
+ +
+
+ + +
+

+
+
+

+
    +'.$cur_error.''."\n"; +?> +
+
+
+
+ + +
+

+
+
+
+
+
+ +
+
+
+
+
+
+ + +
+

+
+
+
+
+ + +
+ + + +
+
+'.$lang_post['Hide smilies'].'
'; + else + $checkboxes[] = ''; +} + +if ($is_admmod) +{ + if ((isset($_POST['form_sent']) && isset($_POST['silent'])) || !isset($_POST['form_sent'])) + $checkboxes[] = ''; + else + $checkboxes[] = ''; +} + +if (!empty($checkboxes)) +{ + +?> +
+
+
+ +
+
+ +
+
+
+ +
+

+
+
+
+'s) + + fid: One or more forum IDs (comma-separated). If ignored, + topics from all readable forums will be pulled. + + nfid: One or more forum IDs (comma-separated) that are to be + excluded. E.g. the ID of a a test forum. + + tid: A topic ID from which to show posts. If a tid is supplied, + fid and nfid are ignored. + + show: Any integer value between 1 and 50. The default is 15. + + order: last_post - show topics ordered by when they were last + posted in, giving information about the reply. + posted - show topics ordered by when they were first + posted, giving information about the original post. + +-----------------------------------------------------------------------------*/ + +define('PUN_QUIET_VISIT', 1); + +if (!defined('PUN_ROOT')) + define('PUN_ROOT', './'); +require PUN_ROOT.'include/common.php'; + +// The length at which topic subjects will be truncated (for HTML output) +if (!defined('FORUM_EXTERN_MAX_SUBJECT_LENGTH')) + define('FORUM_EXTERN_MAX_SUBJECT_LENGTH', 30); + +// If we're a guest and we've sent a username/pass, we can try to authenticate using those details +if ($pun_user['is_guest'] && isset($_SERVER['PHP_AUTH_USER'])) + authenticate_user($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']); + +if ($pun_user['g_read_board'] == '0') +{ + http_authenticate_user(); + exit($lang_common['No view']); +} + +$action = isset($_GET['action']) ? $_GET['action'] : 'feed'; + + +// +// Sends the proper headers for Basic HTTP Authentication +// +function http_authenticate_user() +{ + global $pun_config, $pun_user; + + if (!$pun_user['is_guest']) + return; + + header('WWW-Authenticate: Basic realm="'.$pun_config['o_board_title'].' External Syndication"'); + header('HTTP/1.0 401 Unauthorized'); +} + + +// +// Output $feed as RSS 2.0 +// +function output_rss($feed) +{ + global $lang_common, $pun_config; + + // Send XML/no cache headers + header('Content-Type: application/xml; charset=utf-8'); + header('Expires: '.gmdate('D, d M Y H:i:s').' GMT'); + header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); + header('Pragma: public'); + + echo ''."\n"; + echo ''."\n"; + echo "\t".''."\n"; + echo "\t\t".'<![CDATA['.escape_cdata($feed['title']).']]>'."\n"; + echo "\t\t".''.$feed['link'].''."\n"; + echo "\t\t".''."\n"; + echo "\t\t".''.gmdate('r', count($feed['items']) ? $feed['items'][0]['pubdate'] : time()).''."\n"; + + if ($pun_config['o_show_version'] == '1') + echo "\t\t".'FluxBB '.$pun_config['o_cur_version'].''."\n"; + else + echo "\t\t".'FluxBB'."\n"; + + foreach ($feed['items'] as $item) + { + echo "\t\t".''."\n"; + echo "\t\t\t".'<![CDATA['.escape_cdata($item['title']).']]>'."\n"; + echo "\t\t\t".''.$item['link'].''."\n"; + echo "\t\t\t".''."\n"; + echo "\t\t\t".''."\n"; + echo "\t\t\t".''.gmdate('r', $item['pubdate']).''."\n"; + echo "\t\t\t".''.$item['link'].''."\n"; + + echo "\t\t".''."\n"; + } + + echo "\t".''."\n"; + echo ''."\n"; +} + + +// +// Output $feed as Atom 1.0 +// +function output_atom($feed) +{ + global $lang_common, $pun_config; + + // Send XML/no cache headers + header('Content-Type: application/atom+xml; charset=utf-8'); + header('Expires: '.gmdate('D, d M Y H:i:s').' GMT'); + header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); + header('Pragma: public'); + + echo ''."\n"; + echo ''."\n"; + + echo "\t".'<![CDATA['.escape_cdata($feed['title']).']]>'."\n"; + echo "\t".''."\n"; + echo "\t".''."\n"; + echo "\t".''.gmdate('Y-m-d\TH:i:s\Z', count($feed['items']) ? $feed['items'][0]['pubdate'] : time()).''."\n"; + + if ($pun_config['o_show_version'] == '1') + echo "\t".'FluxBB'."\n"; + else + echo "\t".'FluxBB'."\n"; + + echo "\t".''.$feed['link'].''."\n"; + + $content_tag = ($feed['type'] == 'posts') ? 'content' : 'summary'; + + foreach ($feed['items'] as $item) + { + echo "\t".''."\n"; + echo "\t\t".'<![CDATA['.escape_cdata($item['title']).']]>'."\n"; + echo "\t\t".''."\n"; + echo "\t\t".'<'.$content_tag.' type="html">'."\n"; + echo "\t\t".''."\n"; + echo "\t\t\t".''."\n"; + + if (isset($item['author']['email'])) + echo "\t\t\t".''."\n"; + + if (isset($item['author']['uri'])) + echo "\t\t\t".''.$item['author']['uri'].''."\n"; + + echo "\t\t".''."\n"; + echo "\t\t".''.gmdate('Y-m-d\TH:i:s\Z', $item['pubdate']).''."\n"; + + echo "\t\t".''.$item['link'].''."\n"; + echo "\t".''."\n"; + } + + echo ''."\n"; +} + + +// +// Output $feed as XML +// +function output_xml($feed) +{ + global $lang_common, $pun_config; + + // Send XML/no cache headers + header('Content-Type: application/xml; charset=utf-8'); + header('Expires: '.gmdate('D, d M Y H:i:s').' GMT'); + header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); + header('Pragma: public'); + + echo ''."\n"; + echo ''."\n"; + echo "\t".''.$feed['link'].''."\n"; + + $forum_tag = ($feed['type'] == 'posts') ? 'post' : 'topic'; + + foreach ($feed['items'] as $item) + { + echo "\t".'<'.$forum_tag.' id="'.$item['id'].'">'."\n"; + + echo "\t\t".'<![CDATA['.escape_cdata($item['title']).']]>'."\n"; + echo "\t\t".''.$item['link'].''."\n"; + echo "\t\t".''."\n"; + echo "\t\t".''."\n"; + echo "\t\t\t".''."\n"; + + if (isset($item['author']['email'])) + echo "\t\t\t".''."\n"; + + if (isset($item['author']['uri'])) + echo "\t\t\t".''.$item['author']['uri'].''."\n"; + + echo "\t\t".''."\n"; + echo "\t\t".''.gmdate('r', $item['pubdate']).''."\n"; + + echo "\t".''."\n"; + } + + echo ''."\n"; +} + + +// +// Output $feed as HTML (using
  • tags) +// +function output_html($feed) +{ + + // Send the Content-type header in case the web server is setup to send something else + header('Content-type: text/html; charset=utf-8'); + header('Expires: '.gmdate('D, d M Y H:i:s').' GMT'); + header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); + header('Pragma: public'); + + foreach ($feed['items'] as $item) + { + if (utf8_strlen($item['title']) > FORUM_EXTERN_MAX_SUBJECT_LENGTH) + $subject_truncated = pun_htmlspecialchars(pun_trim(utf8_substr($item['title'], 0, (FORUM_EXTERN_MAX_SUBJECT_LENGTH - 5)))).' …'; + else + $subject_truncated = pun_htmlspecialchars($item['title']); + + echo '
  • '.$subject_truncated.'
  • '."\n"; + } +} + +// Show recent discussions +if ($action == 'feed') +{ + require PUN_ROOT.'include/parser.php'; + + // Determine what type of feed to output + $type = isset($_GET['type']) && in_array($_GET['type'], array('html', 'rss', 'atom', 'xml')) ? $_GET['type'] : 'html'; + + $show = isset($_GET['show']) ? intval($_GET['show']) : 15; + if ($show < 1 || $show > 50) + $show = 15; + + // Was a topic ID supplied? + if (isset($_GET['tid'])) + { + $tid = intval($_GET['tid']); + + // Fetch topic subject + $result = $db->query('SELECT t.subject, t.first_post_id FROM '.$db->prefix.'topics AS t LEFT JOIN '.$db->prefix.'forum_perms AS fp ON (fp.forum_id=t.forum_id AND fp.group_id='.$pun_user['g_id'].') WHERE (fp.read_forum IS NULL OR fp.read_forum=1) AND t.moved_to IS NULL AND t.id='.$tid) or error('Unable to fetch topic info', __FILE__, __LINE__, $db->error()); + if (!$db->num_rows($result)) + { + http_authenticate_user(); + exit($lang_common['Bad request']); + } + + $cur_topic = $db->fetch_assoc($result); + + if ($pun_config['o_censoring'] == '1') + $cur_topic['subject'] = censor_words($cur_topic['subject']); + + // Setup the feed + $feed = array( + 'title' => $pun_config['o_board_title'].$lang_common['Title separator'].$cur_topic['subject'], + 'link' => $pun_config['o_base_url'].'/viewtopic.php?id='.$tid, + 'description' => sprintf($lang_common['RSS description topic'], $cur_topic['subject']), + 'items' => array(), + 'type' => 'posts' + ); + + // Fetch $show posts + $result = $db->query('SELECT p.id, p.poster, p.message, p.hide_smilies, p.posted, p.poster_id, u.email_setting, u.email, p.poster_email FROM '.$db->prefix.'posts AS p INNER JOIN '.$db->prefix.'users AS u ON u.id=p.poster_id WHERE p.topic_id='.$tid.' ORDER BY p.posted DESC LIMIT '.$show) or error('Unable to fetch post info', __FILE__, __LINE__, $db->error()); + while ($cur_post = $db->fetch_assoc($result)) + { + $cur_post['message'] = parse_message($cur_post['message'], $cur_post['hide_smilies']); + + $item = array( + 'id' => $cur_post['id'], + 'title' => $cur_topic['first_post_id'] == $cur_post['id'] ? $cur_topic['subject'] : $lang_common['RSS reply'].$cur_topic['subject'], + 'link' => $pun_config['o_base_url'].'/viewtopic.php?pid='.$cur_post['id'].'#p'.$cur_post['id'], + 'description' => $cur_post['message'], + 'author' => array( + 'name' => $cur_post['poster'], + ), + 'pubdate' => $cur_post['posted'] + ); + + if ($cur_post['poster_id'] > 1) + { + if ($cur_post['email_setting'] == '0' && !$pun_user['is_guest']) + $item['author']['email'] = $cur_post['email']; + + $item['author']['uri'] = $pun_config['o_base_url'].'/profile.php?id='.$cur_post['poster_id']; + } + else if ($cur_post['poster_email'] != '' && !$pun_user['is_guest']) + $item['author']['email'] = $cur_post['poster_email']; + + $feed['items'][] = $item; + } + + $output_func = 'output_'.$type; + $output_func($feed); + } + else + { + $order_posted = isset($_GET['order']) && $_GET['order'] == 'posted'; + $forum_name = ''; + $forum_sql = ''; + + // Were any forum IDs supplied? + if (isset($_GET['fid']) && is_scalar($_GET['fid']) && $_GET['fid'] != '') + { + $fids = explode(',', pun_trim($_GET['fid'])); + $fids = array_map('intval', $fids); + + if (!empty($fids)) + $forum_sql .= ' AND t.forum_id IN('.implode(',', $fids).')'; + + if (count($fids) == 1) + { + // Fetch forum name + $result = $db->query('SELECT f.forum_name FROM '.$db->prefix.'forums AS f LEFT JOIN '.$db->prefix.'forum_perms AS fp ON (fp.forum_id=f.id AND fp.group_id='.$pun_user['g_id'].') WHERE (fp.read_forum IS NULL OR fp.read_forum=1) AND f.id='.$fids[0]) or error('Unable to fetch forum name', __FILE__, __LINE__, $db->error()); + if ($db->num_rows($result)) + $forum_name = $lang_common['Title separator'].$db->result($result); + } + } + + // Any forum IDs to exclude? + if (isset($_GET['nfid']) && is_scalar($_GET['nfid']) && $_GET['nfid'] != '') + { + $nfids = explode(',', pun_trim($_GET['nfid'])); + $nfids = array_map('intval', $nfids); + + if (!empty($nfids)) + $forum_sql .= ' AND t.forum_id NOT IN('.implode(',', $nfids).')'; + } + + // Setup the feed + $feed = array( + 'title' => $pun_config['o_board_title'].$forum_name, + 'link' => $pun_config['o_base_url'].'/index.php', + 'description' => sprintf($lang_common['RSS description'], $pun_config['o_board_title']), + 'items' => array(), + 'type' => 'topics' + ); + + // Fetch $show topics + $result = $db->query('SELECT t.id, t.poster, t.subject, t.posted, t.last_post, t.last_poster, p.message, p.hide_smilies, u.email_setting, u.email, p.poster_id, p.poster_email FROM '.$db->prefix.'topics AS t INNER JOIN '.$db->prefix.'posts AS p ON p.id='.($order_posted ? 't.first_post_id' : 't.last_post_id').' INNER JOIN '.$db->prefix.'users AS u ON u.id=p.poster_id LEFT JOIN '.$db->prefix.'forum_perms AS fp ON (fp.forum_id=t.forum_id AND fp.group_id='.$pun_user['g_id'].') WHERE (fp.read_forum IS NULL OR fp.read_forum=1) AND t.moved_to IS NULL'.$forum_sql.' ORDER BY '.($order_posted ? 't.posted' : 't.last_post').' DESC LIMIT '.$show) or error('Unable to fetch topic info', __FILE__, __LINE__, $db->error()); + while ($cur_topic = $db->fetch_assoc($result)) + { + if ($pun_config['o_censoring'] == '1') + $cur_topic['subject'] = censor_words($cur_topic['subject']); + + $cur_topic['message'] = parse_message($cur_topic['message'], $cur_topic['hide_smilies']); + + $item = array( + 'id' => $cur_topic['id'], + 'title' => $cur_topic['subject'], + 'link' => $pun_config['o_base_url'].($order_posted ? '/viewtopic.php?id='.$cur_topic['id'] : '/viewtopic.php?id='.$cur_topic['id'].'&action=new'), + 'description' => $cur_topic['message'], + 'author' => array( + 'name' => $order_posted ? $cur_topic['poster'] : $cur_topic['last_poster'] + ), + 'pubdate' => $order_posted ? $cur_topic['posted'] : $cur_topic['last_post'] + ); + + if ($cur_topic['poster_id'] > 1) + { + if ($cur_topic['email_setting'] == '0' && !$pun_user['is_guest']) + $item['author']['email'] = $cur_topic['email']; + + $item['author']['uri'] = $pun_config['o_base_url'].'/profile.php?id='.$cur_topic['poster_id']; + } + else if ($cur_topic['poster_email'] != '' && !$pun_user['is_guest']) + $item['author']['email'] = $cur_topic['poster_email']; + + $feed['items'][] = $item; + } + + $output_func = 'output_'.$type; + $output_func($feed); + } + + exit; +} + +// Show users online +else if ($action == 'online' || $action == 'online_full') +{ + // Load the index.php language file + require PUN_ROOT.'lang/'.$pun_config['o_default_lang'].'/index.php'; + + // Fetch users online info and generate strings for output + $num_guests = $num_users = 0; + $users = array(); + + $result = $db->query('SELECT user_id, ident FROM '.$db->prefix.'online WHERE idle=0 ORDER BY ident', true) or error('Unable to fetch online list', __FILE__, __LINE__, $db->error()); + + while ($pun_user_online = $db->fetch_assoc($result)) + { + if ($pun_user_online['user_id'] > 1) + { + $users[] = ($pun_user['g_view_users'] == '1') ? ''.pun_htmlspecialchars($pun_user_online['ident']).'' : pun_htmlspecialchars($pun_user_online['ident']); + ++$num_users; + } + else + ++$num_guests; + } + + // Send the Content-type header in case the web server is setup to send something else + header('Content-type: text/html; charset=utf-8'); + header('Expires: '.gmdate('D, d M Y H:i:s').' GMT'); + header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); + header('Pragma: public'); + + echo sprintf($lang_index['Guests online'], forum_number_format($num_guests)).'
    '."\n"; + + if ($action == 'online_full' && !empty($users)) + echo sprintf($lang_index['Users online'], implode(', ', $users)).'
    '."\n"; + else + echo sprintf($lang_index['Users online'], forum_number_format($num_users)).'
    '."\n"; + + exit; +} + +// Show board statistics +else if ($action == 'stats') +{ + // Load the index.php language file + require PUN_ROOT.'lang/'.$pun_config['o_default_lang'].'/index.php'; + + // Collect some statistics from the database + $result = $db->query('SELECT COUNT(id)-1 FROM '.$db->prefix.'users WHERE group_id!='.PUN_UNVERIFIED) or error('Unable to fetch total user count', __FILE__, __LINE__, $db->error()); + $stats['total_users'] = $db->result($result); + + $result = $db->query('SELECT id, username FROM '.$db->prefix.'users WHERE group_id!='.PUN_UNVERIFIED.' ORDER BY registered DESC LIMIT 1') or error('Unable to fetch newest registered user', __FILE__, __LINE__, $db->error()); + $stats['last_user'] = $db->fetch_assoc($result); + + $result = $db->query('SELECT SUM(num_topics), SUM(num_posts) FROM '.$db->prefix.'forums') or error('Unable to fetch topic/post count', __FILE__, __LINE__, $db->error()); + list($stats['total_topics'], $stats['total_posts']) = $db->fetch_row($result); + + // Send the Content-type header in case the web server is setup to send something else + header('Content-type: text/html; charset=utf-8'); + header('Expires: '.gmdate('D, d M Y H:i:s').' GMT'); + header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); + header('Pragma: public'); + + echo sprintf($lang_index['No of users'], forum_number_format($stats['total_users'])).'
    '."\n"; + echo sprintf($lang_index['Newest user'], (($pun_user['g_view_users'] == '1') ? ''.pun_htmlspecialchars($stats['last_user']['username']).'' : pun_htmlspecialchars($stats['last_user']['username']))).'
    '."\n"; + echo sprintf($lang_index['No of topics'], forum_number_format($stats['total_topics'])).'
    '."\n"; + echo sprintf($lang_index['No of posts'], forum_number_format($stats['total_posts'])).'
    '."\n"; + + exit; +} + +// If we end up here, the script was called with some wacky parameters +exit($lang_common['Bad request']); diff --git a/footer.php b/footer.php new file mode 100644 index 0000000..c308c9e --- /dev/null +++ b/footer.php @@ -0,0 +1,201 @@ +', $tpl_temp, $tpl_main); +ob_end_clean(); +// END SUBST - + + +// START SUBST - +ob_start(); + +?> +
    +

    +
    +'."\n"; + + if ($footer_style == 'viewforum') + { + echo "\t\t\t".'
    '."\n"; + echo "\t\t\t\t".'
    '.$lang_forum['Mod controls'].'
    '."\n"; + echo "\t\t\t\t".'
    '.$lang_common['Moderate forum'].'
    '."\n"; + echo "\t\t\t".'
    '."\n"; + } + else if ($footer_style == 'viewtopic') + { + echo "\t\t\t".'
    '."\n"; + echo "\t\t\t\t".'
    '.$lang_topic['Mod controls'].'
    '."\n"; + echo "\t\t\t\t".'
    '.$lang_common['Moderate topic'].'
    '."\n"; + echo "\t\t\t\t".'
    '.$lang_common['Move topic'].'
    '."\n"; + + if ($cur_topic['closed'] == '1') + echo "\t\t\t\t".'
    '.$lang_common['Open topic'].'
    '."\n"; + else + echo "\t\t\t\t".'
    '.$lang_common['Close topic'].'
    '."\n"; + + if ($cur_topic['sticky'] == '1') + echo "\t\t\t\t".'
    '.$lang_common['Unstick topic'].'
    '."\n"; + else + echo "\t\t\t\t".'
    '.$lang_common['Stick topic'].'
    '."\n"; + + echo "\t\t\t".'
    '."\n"; + } + + echo "\t\t\t".'
    '."\n\t\t".'
    '."\n"; +} + +?> +
    +'."\n"; + + if (!$pun_user['is_guest'] && $pun_user['g_search'] == '1') + { + echo "\t\t\t\t".''."\n"; + } + else + { + if ($pun_user['g_search'] == '1') + { + echo "\t\t\t\t".''."\n"; + } + } + + echo "\t\t\t".'
    '."\n"; +} +else if ($footer_style == 'viewforum' || $footer_style == 'viewtopic') +{ + echo "\t\t\t".'
    '."\n"; + + // Display the "Jump to" drop list + if ($pun_config['o_quickjump'] == '1') + { + // Load cached quick jump + if (file_exists(FORUM_CACHE_DIR.'cache_quickjump_'.$pun_user['g_id'].'.php')) + include FORUM_CACHE_DIR.'cache_quickjump_'.$pun_user['g_id'].'.php'; + + if (!defined('PUN_QJ_LOADED')) + { + if (!defined('FORUM_CACHE_FUNCTIONS_LOADED')) + require PUN_ROOT.'include/cache.php'; + + generate_quickjump_cache($pun_user['g_id']); + require FORUM_CACHE_DIR.'cache_quickjump_'.$pun_user['g_id'].'.php'; + } + } + + echo "\t\t\t".'
    '."\n"; +} + +?> +
    +'.$lang_common['RSS active topics feed'].'

    '."\n"; + else if ($pun_config['o_feed_type'] == '2') + echo "\t\t\t\t".''."\n"; +} +else if ($footer_style == 'viewforum') +{ + if ($pun_config['o_feed_type'] == '1') + echo "\t\t\t\t".''."\n"; + else if ($pun_config['o_feed_type'] == '2') + echo "\t\t\t\t".''."\n"; +} +else if ($footer_style == 'viewtopic') +{ + if ($pun_config['o_feed_type'] == '1') + echo "\t\t\t\t".''."\n"; + else if ($pun_config['o_feed_type'] == '2') + echo "\t\t\t\t".''."\n"; +} + +?> +

    FluxBB'.(($pun_config['o_show_version'] == '1') ? ' '.$pun_config['o_cur_version'] : '')) ?>

    +
    +
    +
    + + +[ '; + + // Calculate script generation time + $time_diff = sprintf('%.3f', get_microtime() - $pun_start); + echo sprintf($lang_common['Querytime'], $time_diff, $db->get_num_queries()); + + if (function_exists('memory_get_usage')) + { + echo ' - '.sprintf($lang_common['Memory usage'], file_size(memory_get_usage())); + + if (function_exists('memory_get_peak_usage')) + echo ' '.sprintf($lang_common['Peak usage'], file_size(memory_get_peak_usage())); + } + + echo ' ]

    '."\n"; +} + + +// End the transaction +$db->end_transaction(); + +// Display executed queries (if enabled) +if (defined('PUN_SHOW_QUERIES')) + display_saved_queries(); + +$tpl_temp = trim(ob_get_contents()); +$tpl_main = str_replace('', $tpl_temp, $tpl_main); +ob_end_clean(); +// END SUBST - + + +// Close the db connection (and free up any result data) +$db->close(); + +// Spit out the page +exit($tpl_main); diff --git a/header.php b/header.php new file mode 100644 index 0000000..78335e1 --- /dev/null +++ b/header.php @@ -0,0 +1,244 @@ + +preg_match_all('##', $tpl_main, $pun_includes, PREG_SET_ORDER); + +foreach ($pun_includes as $cur_include) +{ + ob_start(); + + // Allow for overriding user includes, too. + if (file_exists($tpl_inc_dir.$cur_include[1].'.'.$cur_include[2])) + require $tpl_inc_dir.$cur_include[1].'.'.$cur_include[2]; + else if (file_exists(PUN_ROOT.'include/user/'.$cur_include[1].'.'.$cur_include[2])) + require PUN_ROOT.'include/user/'.$cur_include[1].'.'.$cur_include[2]; + else + error(sprintf($lang_common['Pun include error'], htmlspecialchars($cur_include[0]), basename($tpl_file))); + + $tpl_temp = ob_get_contents(); + $tpl_main = str_replace($cur_include[0], $tpl_temp, $tpl_main); + ob_end_clean(); +} +// END SUBST - + + +// START SUBST - +$tpl_main = str_replace('', $lang_common['lang_identifier'], $tpl_main); +// END SUBST - + + +// START SUBST - +$tpl_main = str_replace('', $lang_common['lang_direction'], $tpl_main); +// END SUBST - + + +// START SUBST - +ob_start(); + +// Define $p if its not set to avoid a PHP notice +$p = isset($p) ? $p : null; + +// Is this a page that we want search index spiders to index? +if (!defined('PUN_ALLOW_INDEX')) + echo ''."\n"; + +?> +<?php echo generate_page_title($page_title, $p) ?> + +'."\n"; + else + echo ''."\n"; +} + +if (isset($required_fields)) +{ + // Output JavaScript to validate form (make sure required fields are filled out) + +?> + +'."\n"; + +if (isset($page_head)) + echo implode("\n", $page_head)."\n"; + +$tpl_temp = trim(ob_get_contents()); +$tpl_main = str_replace('', $tpl_temp, $tpl_main); +ob_end_clean(); +// END SUBST - + + +// START SUBST - +if (isset($focus_element)) +{ + $tpl_main = str_replace('', '', $tpl_main); +} +// END SUBST - + + +// START SUBST - +$tpl_main = str_replace('', htmlspecialchars(basename($_SERVER['PHP_SELF'], '.php')), $tpl_main); +// END SUBST - + + +// START SUBST - +$tpl_main = str_replace('', '

    '.pun_htmlspecialchars($pun_config['o_board_title']).'

    ', $tpl_main); +// END SUBST - + + +// START SUBST - +$tpl_main = str_replace('', '
    '.$pun_config['o_board_desc'].'
    ', $tpl_main); +// END SUBST - + + +// START SUBST - +$tpl_main = str_replace('','
    '."\n\t\t\t". generate_navlinks()."\n\t\t".'
    ', $tpl_main); +// END SUBST - + + +// START SUBST - +if ($pun_user['is_guest']) + $tpl_temp = '
    '."\n\t\t\t".'

    '.$lang_common['Not logged in'].'

    '."\n\t\t".'
    '; +else +{ + $tpl_temp = '
    '."\n\t\t\t".'
      '."\n\t\t\t\t".'
    • '.$lang_common['Logged in as'].' '.pun_htmlspecialchars($pun_user['username']).'
    • '."\n\t\t\t\t".'
    • '.sprintf($lang_common['Last visit'], format_time($pun_user['last_visit'])).'
    • '; + + if ($pun_user['is_admmod']) + { + if ($pun_config['o_report_method'] == '0' || $pun_config['o_report_method'] == '2') + { + $result_header = $db->query('SELECT 1 FROM '.$db->prefix.'reports WHERE zapped IS NULL') or error('Unable to fetch reports info', __FILE__, __LINE__, $db->error()); + + if ($db->result($result_header)) + $tpl_temp .= "\n\t\t\t\t".''; + } + + if ($pun_config['o_maintenance'] == '1') + $tpl_temp .= "\n\t\t\t\t".''; + } + + if (in_array(basename($_SERVER['PHP_SELF']), array('index.php', 'search.php'))) + $tpl_temp .= "\n\t\t\t".'
    '."\n\t\t\t".''."\n\t\t\t".'
    '."\n\t\t".'
    '; + else if (basename($_SERVER['PHP_SELF']) == 'viewforum.php') + $tpl_temp .= "\n\t\t\t".''."\n\t\t\t".''."\n\t\t\t".'
    '."\n\t\t".''; + else + $tpl_temp .= "\n\t\t\t".''."\n\t\t\t".'
    '."\n\t\t".''; +} + +$tpl_main = str_replace('', $tpl_temp, $tpl_main); +// END SUBST - + + +// START SUBST - +if ($pun_config['o_announcement'] == '1') +{ + ob_start(); + +?> +
    +

    +
    +
    +
    +
    +
    +
    +', $tpl_temp, $tpl_main); + ob_end_clean(); +} +else + $tpl_main = str_replace('', '', $tpl_main); +// END SUBST - + + +// START SUBST - +ob_start(); + + +define('PUN_HEADER', 1); diff --git a/help.php b/help.php new file mode 100644 index 0000000..1d828fb --- /dev/null +++ b/help.php @@ -0,0 +1,144 @@ + +

    +
    +
    +

    +

    +
    +
    +

    +
    +
    +

    +

    [b][/b]

    +

    [u][/u]

    +

    [i][/i]

    +

    [s][/s]

    +

    [del][/del]

    +

    [ins][/ins]

    +

    [em][/em]

    +

    [color=#FF0000][/color]

    +

    [color=blue][/color]

    +

    [h][/h]

    +
    +
    +

    +
    +
    +

    +

    [url=][/url]

    +

    [url][/url]

    +

    [email]myname@mydomain.com[/email] myname@mydomain.com

    +

    [email=myname@mydomain.com][/email]

    +
    +
    +

    +

    [img=FluxBB bbcode test]img/test.png[/img] FluxBB bbcode test

    +
    +
    +

    +
    +
    +

    +

    [quote=James][/quote]

    +

    +
    +
    James

    +
    +

    +

    [quote][/quote]

    +

    +
    +

    +
    +

    +
    +
    +

    +
    +
    +

    +

    [code][/code]

    +

    +
    +
    +
    +
    +
    +

    +
    +
    +

    +

    [list][*][/*][*][/*][*][/*][/list] +

    +
    +
    +
    +

    [list=1][*][/*][*][/*][*][/*][/list] +

    +
    +
    +
    +

    [list=a][*][/*][*][/*][*][/*][/list] +

    +
    +
    +
    +
    +
    +

    +
    +
    +

    +

    [b][u][/u][/b]

    +
    +
    +

    +
    +
    +

    + $smiley_img) + $smiley_groups[$smiley_img][] = $smiley_text; + +foreach ($smiley_groups as $smiley_img => $smiley_texts) + echo "\t\t".'

    '.implode(' '.$lang_common['and'].' ', $smiley_texts).' '.$lang_help['produces'].' '.$smiley_texts[0].'

    '."\n"; +?> +
    +
    +.. diff --git a/img/index.html b/img/index.html new file mode 100644 index 0000000..89337b2 --- /dev/null +++ b/img/index.html @@ -0,0 +1 @@ +.. diff --git a/img/smilies/big_smile.png b/img/smilies/big_smile.png new file mode 100644 index 0000000..b29719b Binary files /dev/null and b/img/smilies/big_smile.png differ diff --git a/img/smilies/cool.png b/img/smilies/cool.png new file mode 100644 index 0000000..a875361 Binary files /dev/null and b/img/smilies/cool.png differ diff --git a/img/smilies/hmm.png b/img/smilies/hmm.png new file mode 100644 index 0000000..69e416a Binary files /dev/null and b/img/smilies/hmm.png differ diff --git a/img/smilies/index.html b/img/smilies/index.html new file mode 100644 index 0000000..89337b2 --- /dev/null +++ b/img/smilies/index.html @@ -0,0 +1 @@ +.. diff --git a/img/smilies/lol.png b/img/smilies/lol.png new file mode 100644 index 0000000..dd9058b Binary files /dev/null and b/img/smilies/lol.png differ diff --git a/img/smilies/mad.png b/img/smilies/mad.png new file mode 100644 index 0000000..011079d Binary files /dev/null and b/img/smilies/mad.png differ diff --git a/img/smilies/neutral.png b/img/smilies/neutral.png new file mode 100644 index 0000000..9bc5ca0 Binary files /dev/null and b/img/smilies/neutral.png differ diff --git a/img/smilies/roll.png b/img/smilies/roll.png new file mode 100644 index 0000000..e2e8e2a Binary files /dev/null and b/img/smilies/roll.png differ diff --git a/img/smilies/sad.png b/img/smilies/sad.png new file mode 100644 index 0000000..c14e144 Binary files /dev/null and b/img/smilies/sad.png differ diff --git a/img/smilies/smile.png b/img/smilies/smile.png new file mode 100644 index 0000000..44cc239 Binary files /dev/null and b/img/smilies/smile.png differ diff --git a/img/smilies/tongue.png b/img/smilies/tongue.png new file mode 100644 index 0000000..5302c89 Binary files /dev/null and b/img/smilies/tongue.png differ diff --git a/img/smilies/wink.png b/img/smilies/wink.png new file mode 100644 index 0000000..595c1fe Binary files /dev/null and b/img/smilies/wink.png differ diff --git a/img/smilies/yikes.png b/img/smilies/yikes.png new file mode 100644 index 0000000..bb4aefd Binary files /dev/null and b/img/smilies/yikes.png differ diff --git a/img/test.png b/img/test.png new file mode 100644 index 0000000..7b46d9e Binary files /dev/null and b/img/test.png differ diff --git a/include/cache.php b/include/cache.php new file mode 100644 index 0000000..55d0e96 --- /dev/null +++ b/include/cache.php @@ -0,0 +1,145 @@ +query('SELECT * FROM '.$db->prefix.'config', true) or error('Unable to fetch forum config', __FILE__, __LINE__, $db->error()); + while ($cur_config_item = $db->fetch_row($result)) + $output[$cur_config_item[0]] = $cur_config_item[1]; + + // Output config as PHP code + $fh = @fopen(FORUM_CACHE_DIR.'cache_config.php', 'wb'); + if (!$fh) + error('Unable to write configuration cache file to cache directory. Please make sure PHP has write access to the directory \'cache\'', __FILE__, __LINE__); + + fwrite($fh, ''); + + fclose($fh); +} + + +// +// Generate the bans cache PHP script +// +function generate_bans_cache() +{ + global $db; + + // Get the ban list from the DB + $result = $db->query('SELECT * FROM '.$db->prefix.'bans', true) or error('Unable to fetch ban list', __FILE__, __LINE__, $db->error()); + + $output = array(); + while ($cur_ban = $db->fetch_assoc($result)) + $output[] = $cur_ban; + + // Output ban list as PHP code + $fh = @fopen(FORUM_CACHE_DIR.'cache_bans.php', 'wb'); + if (!$fh) + error('Unable to write bans cache file to cache directory. Please make sure PHP has write access to the directory \'cache\'', __FILE__, __LINE__); + + fwrite($fh, ''); + + fclose($fh); +} + + +// +// Generate the ranks cache PHP script +// +function generate_ranks_cache() +{ + global $db; + + // Get the rank list from the DB + $result = $db->query('SELECT * FROM '.$db->prefix.'ranks ORDER BY min_posts', true) or error('Unable to fetch rank list', __FILE__, __LINE__, $db->error()); + + $output = array(); + while ($cur_rank = $db->fetch_assoc($result)) + $output[] = $cur_rank; + + // Output ranks list as PHP code + $fh = @fopen(FORUM_CACHE_DIR.'cache_ranks.php', 'wb'); + if (!$fh) + error('Unable to write ranks cache file to cache directory. Please make sure PHP has write access to the directory \'cache\'', __FILE__, __LINE__); + + fwrite($fh, ''); + + fclose($fh); +} + + +// +// Generate quick jump cache PHP scripts +// +function generate_quickjump_cache($group_id = false) +{ + global $db, $lang_common, $pun_user; + + // If a group_id was supplied, we generate the quick jump cache for that group only + if ($group_id !== false) + $groups[0] = $group_id; + else + { + // A group_id was now supplied, so we generate the quick jump cache for all groups + $result = $db->query('SELECT g_id FROM '.$db->prefix.'groups') or error('Unable to fetch user group list', __FILE__, __LINE__, $db->error()); + $num_groups = $db->num_rows($result); + + for ($i = 0; $i < $num_groups; ++$i) + $groups[] = $db->result($result, $i); + } + + // Loop through the groups in $groups and output the cache for each of them + foreach ($groups as $group_id) + { + // Output quick jump as PHP code + $fh = @fopen(FORUM_CACHE_DIR.'cache_quickjump_'.$group_id.'.php', 'wb'); + if (!$fh) + error('Unable to write quick jump cache file to cache directory. Please make sure PHP has write access to the directory \'cache\'', __FILE__, __LINE__); + + $output = ''; + $output .= "\t\t\t\t".'
    '."\n\t\t\t\t\t".'
    '."\n\t\t\t\t".'
    '."\n"; + + fwrite($fh, $output); + + fclose($fh); + } +} + +define('FORUM_CACHE_FUNCTIONS_LOADED', true); diff --git a/include/common.php b/include/common.php new file mode 100644 index 0000000..1ad999b --- /dev/null +++ b/include/common.php @@ -0,0 +1,182 @@ +install.php to install FluxBB first.'); + +// Load the functions script +require PUN_ROOT.'include/functions.php'; + +// Load UTF-8 functions +require PUN_ROOT.'include/utf8/utf8.php'; + +// Strip out "bad" UTF-8 characters +forum_remove_bad_characters(); + +// Reverse the effect of register_globals +forum_unregister_globals(); + +// Record the start time (will be used to calculate the generation time for the page) +$pun_start = get_microtime(); + +// Make sure PHP reports all errors except E_NOTICE. FluxBB supports E_ALL, but a lot of scripts it may interact with, do not +error_reporting(E_ALL ^ E_NOTICE); + +// Force POSIX locale (to prevent functions such as strtolower() from messing up UTF-8 strings) +setlocale(LC_CTYPE, 'C'); + +// Turn off magic_quotes_runtime +if (get_magic_quotes_runtime()) + set_magic_quotes_runtime(0); + +// Strip slashes from GET/POST/COOKIE (if magic_quotes_gpc is enabled) +if (get_magic_quotes_gpc()) +{ + function stripslashes_array($array) + { + return is_array($array) ? array_map('stripslashes_array', $array) : stripslashes($array); + } + + $_GET = stripslashes_array($_GET); + $_POST = stripslashes_array($_POST); + $_COOKIE = stripslashes_array($_COOKIE); + $_REQUEST = stripslashes_array($_REQUEST); +} + +// If a cookie name is not specified in config.php, we use the default (pun_cookie) +if (empty($cookie_name)) + $cookie_name = 'pun_cookie'; + +// If the cache directory is not specified, we use the default setting +if (!defined('FORUM_CACHE_DIR')) + define('FORUM_CACHE_DIR', PUN_ROOT.'cache/'); + +// Define a few commonly used constants +define('PUN_UNVERIFIED', 0); +define('PUN_ADMIN', 1); +define('PUN_MOD', 2); +define('PUN_GUEST', 3); +define('PUN_MEMBER', 4); + +// Load DB abstraction layer and connect +require PUN_ROOT.'include/dblayer/common_db.php'; + +// Start a transaction +$db->start_transaction(); + +// Load cached config +if (file_exists(FORUM_CACHE_DIR.'cache_config.php')) + include FORUM_CACHE_DIR.'cache_config.php'; + +if (!defined('PUN_CONFIG_LOADED')) +{ + if (!defined('FORUM_CACHE_FUNCTIONS_LOADED')) + require PUN_ROOT.'include/cache.php'; + + generate_config_cache(); + require FORUM_CACHE_DIR.'cache_config.php'; +} + +// Verify that we are running the proper database schema revision +if (!isset($pun_config['o_database_revision']) || $pun_config['o_database_revision'] < FORUM_DB_REVISION || + !isset($pun_config['o_searchindex_revision']) || $pun_config['o_searchindex_revision'] < FORUM_SI_REVISION || + !isset($pun_config['o_parser_revision']) || $pun_config['o_parser_revision'] < FORUM_PARSER_REVISION || + version_compare($pun_config['o_cur_version'], FORUM_VERSION, '<')) + exit('Your FluxBB database is out-of-date and must be upgraded in order to continue. Please run db_update.php in order to complete the upgrade process.'); + +// Enable output buffering +if (!defined('PUN_DISABLE_BUFFERING')) +{ + // Should we use gzip output compression? + if ($pun_config['o_gzip'] && extension_loaded('zlib')) + ob_start('ob_gzhandler'); + else + ob_start(); +} + +// Define standard date/time formats +$forum_time_formats = array($pun_config['o_time_format'], 'H:i:s', 'H:i', 'g:i:s a', 'g:i a'); +$forum_date_formats = array($pun_config['o_date_format'], 'Y-m-d', 'Y-d-m', 'd-m-Y', 'm-d-Y', 'M j Y', 'jS M Y'); + +// Check/update/set cookie and fetch user info +$pun_user = array(); +check_cookie($pun_user); + +// Attempt to load the common language file +if (file_exists(PUN_ROOT.'lang/'.$pun_user['language'].'/common.php')) + include PUN_ROOT.'lang/'.$pun_user['language'].'/common.php'; +else + error('There is no valid language pack \''.pun_htmlspecialchars($pun_user['language']).'\' installed. Please reinstall a language of that name'); + +// Check if we are to display a maintenance message +if ($pun_config['o_maintenance'] && $pun_user['g_id'] > PUN_ADMIN && !defined('PUN_TURN_OFF_MAINT')) + maintenance_message(); + +// Load cached bans +if (file_exists(FORUM_CACHE_DIR.'cache_bans.php')) + include FORUM_CACHE_DIR.'cache_bans.php'; + +if (!defined('PUN_BANS_LOADED')) +{ + if (!defined('FORUM_CACHE_FUNCTIONS_LOADED')) + require PUN_ROOT.'include/cache.php'; + + generate_bans_cache(); + require FORUM_CACHE_DIR.'cache_bans.php'; +} + +// Check if current user is banned +check_bans(); + +// Update online list +update_users_online(); + +// Check to see if we logged in without a cookie being set +if ($pun_user['is_guest'] && isset($_GET['login'])) + message($lang_common['No cookie']); + +if (!defined('PUN_MAX_POSTSIZE')) + define('PUN_MAX_POSTSIZE', 65535); + +if (!defined('PUN_SEARCH_MIN_WORD')) + define('PUN_SEARCH_MIN_WORD', 3); +if (!defined('PUN_SEARCH_MAX_WORD')) + define('PUN_SEARCH_MAX_WORD', 20); diff --git a/include/common_admin.php b/include/common_admin.php new file mode 100644 index 0000000..7a5603d --- /dev/null +++ b/include/common_admin.php @@ -0,0 +1,133 @@ + +
    +
    +

    +
    +
    +
      + > + > + > + > + > + > + > + > + > + > + > + > + > +
    +
    +
    + +

    + + +
    + +query('SELECT id FROM '.$db->prefix.'topics WHERE forum_id='.$forum_id.$extra_sql, true) or error('Unable to fetch topics', __FILE__, __LINE__, $db->error()); + + $topic_ids = ''; + while ($row = $db->fetch_row($result)) + $topic_ids .= (($topic_ids != '') ? ',' : '').$row[0]; + + if ($topic_ids != '') + { + // Fetch posts to prune + $result = $db->query('SELECT id FROM '.$db->prefix.'posts WHERE topic_id IN('.$topic_ids.')', true) or error('Unable to fetch posts', __FILE__, __LINE__, $db->error()); + + $post_ids = ''; + while ($row = $db->fetch_row($result)) + $post_ids .= (($post_ids != '') ? ',' : '').$row[0]; + + if ($post_ids != '') + { + // Delete topics + $db->query('DELETE FROM '.$db->prefix.'topics WHERE id IN('.$topic_ids.')') or error('Unable to prune topics', __FILE__, __LINE__, $db->error()); + // Delete subscriptions + $db->query('DELETE FROM '.$db->prefix.'subscriptions WHERE topic_id IN('.$topic_ids.')') or error('Unable to prune subscriptions', __FILE__, __LINE__, $db->error()); + // Delete posts + $db->query('DELETE FROM '.$db->prefix.'posts WHERE id IN('.$post_ids.')') or error('Unable to prune posts', __FILE__, __LINE__, $db->error()); + + // We removed a bunch of posts, so now we have to update the search index + require_once PUN_ROOT.'include/search_idx.php'; + strip_search_index($post_ids); + } + } +} diff --git a/include/dblayer/common_db.php b/include/dblayer/common_db.php new file mode 100644 index 0000000..121d895 --- /dev/null +++ b/include/dblayer/common_db.php @@ -0,0 +1,48 @@ +.. diff --git a/include/dblayer/mysql.php b/include/dblayer/mysql.php new file mode 100644 index 0000000..c595da4 --- /dev/null +++ b/include/dblayer/mysql.php @@ -0,0 +1,347 @@ + 'INT(10) UNSIGNED AUTO_INCREMENT' + ); + + + function DBLayer($db_host, $db_username, $db_password, $db_name, $db_prefix, $p_connect) + { + $this->prefix = $db_prefix; + + if ($p_connect) + $this->link_id = @mysql_pconnect($db_host, $db_username, $db_password); + else + $this->link_id = @mysql_connect($db_host, $db_username, $db_password); + + if ($this->link_id) + { + if (!@mysql_select_db($db_name, $this->link_id)) + error('Unable to select database. MySQL reported: '.mysql_error(), __FILE__, __LINE__); + } + else + error('Unable to connect to MySQL server. MySQL reported: '.mysql_error(), __FILE__, __LINE__); + + // Setup the client-server character set (UTF-8) + if (!defined('FORUM_NO_SET_NAMES')) + $this->set_names('utf8'); + + return $this->link_id; + } + + + function start_transaction() + { + return; + } + + + function end_transaction() + { + return; + } + + + function query($sql, $unbuffered = false) + { + if (defined('PUN_SHOW_QUERIES')) + $q_start = get_microtime(); + + if ($unbuffered) + $this->query_result = @mysql_unbuffered_query($sql, $this->link_id); + else + $this->query_result = @mysql_query($sql, $this->link_id); + + if ($this->query_result) + { + if (defined('PUN_SHOW_QUERIES')) + $this->saved_queries[] = array($sql, sprintf('%.5f', get_microtime() - $q_start)); + + ++$this->num_queries; + + return $this->query_result; + } + else + { + if (defined('PUN_SHOW_QUERIES')) + $this->saved_queries[] = array($sql, 0); + + return false; + } + } + + + function result($query_id = 0, $row = 0, $col = 0) + { + return ($query_id) ? @mysql_result($query_id, $row, $col) : false; + } + + + function fetch_assoc($query_id = 0) + { + return ($query_id) ? @mysql_fetch_assoc($query_id) : false; + } + + + function fetch_row($query_id = 0) + { + return ($query_id) ? @mysql_fetch_row($query_id) : false; + } + + + function num_rows($query_id = 0) + { + return ($query_id) ? @mysql_num_rows($query_id) : false; + } + + + function affected_rows() + { + return ($this->link_id) ? @mysql_affected_rows($this->link_id) : false; + } + + + function insert_id() + { + return ($this->link_id) ? @mysql_insert_id($this->link_id) : false; + } + + + function get_num_queries() + { + return $this->num_queries; + } + + + function get_saved_queries() + { + return $this->saved_queries; + } + + + function free_result($query_id = false) + { + return ($query_id) ? @mysql_free_result($query_id) : false; + } + + + function escape($str) + { + if (is_array($str)) + return ''; + else if (function_exists('mysql_real_escape_string')) + return mysql_real_escape_string($str, $this->link_id); + else + return mysql_escape_string($str); + } + + + function error() + { + $result['error_sql'] = @current(@end($this->saved_queries)); + $result['error_no'] = @mysql_errno($this->link_id); + $result['error_msg'] = @mysql_error($this->link_id); + + return $result; + } + + + function close() + { + if ($this->link_id) + { + if ($this->query_result) + @mysql_free_result($this->query_result); + + return @mysql_close($this->link_id); + } + else + return false; + } + + function set_names($names) + { + return $this->query('SET NAMES \''.$this->escape($names).'\''); + } + + function get_version() + { + $result = $this->query('SELECT VERSION()'); + + return array( + 'name' => 'MySQL Standard', + 'version' => preg_replace('/^([^-]+).*$/', '\\1', $this->result($result)) + ); + } + + function table_exists($table_name, $no_prefix = false) + { + $result = $this->query('SHOW TABLES LIKE \''.($no_prefix ? '' : $this->prefix).$this->escape($table_name).'\''); + return $this->num_rows($result) > 0; + } + + + function field_exists($table_name, $field_name, $no_prefix = false) + { + $result = $this->query('SHOW COLUMNS FROM '.($no_prefix ? '' : $this->prefix).$table_name.' LIKE \''.$this->escape($field_name).'\''); + return $this->num_rows($result) > 0; + } + + + function index_exists($table_name, $index_name, $no_prefix = false) + { + $exists = false; + + $result = $this->query('SHOW INDEX FROM '.($no_prefix ? '' : $this->prefix).$table_name); + while ($cur_index = $this->fetch_assoc($result)) + { + if ($cur_index['Key_name'] == ($no_prefix ? '' : $this->prefix).$table_name.'_'.$index_name) + { + $exists = true; + break; + } + } + + return $exists; + } + + + function create_table($table_name, $schema, $no_prefix = false) + { + if ($this->table_exists($table_name, $no_prefix)) + return true; + + $query = 'CREATE TABLE '.($no_prefix ? '' : $this->prefix).$table_name." (\n"; + + // Go through every schema element and add it to the query + foreach ($schema['FIELDS'] as $field_name => $field_data) + { + $field_data['datatype'] = preg_replace(array_keys($this->datatype_transformations), array_values($this->datatype_transformations), $field_data['datatype']); + + $query .= $field_name.' '.$field_data['datatype']; + + if (isset($field_data['collation'])) + $query .= 'CHARACTER SET utf8 COLLATE utf8_'.$field_data['collation']; + + if (!$field_data['allow_null']) + $query .= ' NOT NULL'; + + if (isset($field_data['default'])) + $query .= ' DEFAULT '.$field_data['default']; + + $query .= ",\n"; + } + + // If we have a primary key, add it + if (isset($schema['PRIMARY KEY'])) + $query .= 'PRIMARY KEY ('.implode(',', $schema['PRIMARY KEY']).'),'."\n"; + + // Add unique keys + if (isset($schema['UNIQUE KEYS'])) + { + foreach ($schema['UNIQUE KEYS'] as $key_name => $key_fields) + $query .= 'UNIQUE KEY '.($no_prefix ? '' : $this->prefix).$table_name.'_'.$key_name.'('.implode(',', $key_fields).'),'."\n"; + } + + // Add indexes + if (isset($schema['INDEXES'])) + { + foreach ($schema['INDEXES'] as $index_name => $index_fields) + $query .= 'KEY '.($no_prefix ? '' : $this->prefix).$table_name.'_'.$index_name.'('.implode(',', $index_fields).'),'."\n"; + } + + // We remove the last two characters (a newline and a comma) and add on the ending + $query = substr($query, 0, strlen($query) - 2)."\n".') ENGINE = '.(isset($schema['ENGINE']) ? $schema['ENGINE'] : 'MyISAM').' CHARACTER SET utf8'; + + return $this->query($query) ? true : false; + } + + + function drop_table($table_name, $no_prefix = false) + { + if (!$this->table_exists($table_name, $no_prefix)) + return true; + + return $this->query('DROP TABLE '.($no_prefix ? '' : $this->prefix).$table_name) ? true : false; + } + + + function add_field($table_name, $field_name, $field_type, $allow_null, $default_value = null, $after_field = null, $no_prefix = false) + { + if ($this->field_exists($table_name, $field_name, $no_prefix)) + return true; + + $field_type = preg_replace(array_keys($this->datatype_transformations), array_values($this->datatype_transformations), $field_type); + + if ($default_value !== null && !is_int($default_value) && !is_float($default_value)) + $default_value = '\''.$this->escape($default_value).'\''; + + return $this->query('ALTER TABLE '.($no_prefix ? '' : $this->prefix).$table_name.' ADD '.$field_name.' '.$field_type.($allow_null ? ' ' : ' NOT NULL').($default_value !== null ? ' DEFAULT '.$default_value : ' ').($after_field != null ? ' AFTER '.$after_field : '')) ? true : false; + } + + + function alter_field($table_name, $field_name, $field_type, $allow_null, $default_value = null, $after_field = null, $no_prefix = false) + { + if (!$this->field_exists($table_name, $field_name, $no_prefix)) + return true; + + $field_type = preg_replace(array_keys($this->datatype_transformations), array_values($this->datatype_transformations), $field_type); + + if ($default_value !== null && !is_int($default_value) && !is_float($default_value)) + $default_value = '\''.$this->escape($default_value).'\''; + + return $this->query('ALTER TABLE '.($no_prefix ? '' : $this->prefix).$table_name.' MODIFY '.$field_name.' '.$field_type.($allow_null ? ' ' : ' NOT NULL').($default_value !== null ? ' DEFAULT '.$default_value : ' ').($after_field != null ? ' AFTER '.$after_field : '')) ? true : false; + } + + + function drop_field($table_name, $field_name, $no_prefix = false) + { + if (!$this->field_exists($table_name, $field_name, $no_prefix)) + return true; + + return $this->query('ALTER TABLE '.($no_prefix ? '' : $this->prefix).$table_name.' DROP '.$field_name) ? true : false; + } + + + function add_index($table_name, $index_name, $index_fields, $unique = false, $no_prefix = false) + { + if ($this->index_exists($table_name, $index_name, $no_prefix)) + return true; + + return $this->query('ALTER TABLE '.($no_prefix ? '' : $this->prefix).$table_name.' ADD '.($unique ? 'UNIQUE ' : '').'INDEX '.($no_prefix ? '' : $this->prefix).$table_name.'_'.$index_name.' ('.implode(',', $index_fields).')') ? true : false; + } + + + function drop_index($table_name, $index_name, $no_prefix = false) + { + if (!$this->index_exists($table_name, $index_name, $no_prefix)) + return true; + + return $this->query('ALTER TABLE '.($no_prefix ? '' : $this->prefix).$table_name.' DROP INDEX '.($no_prefix ? '' : $this->prefix).$table_name.'_'.$index_name) ? true : false; + } + + function truncate_table($table_name, $no_prefix = false) + { + return $this->query('TRUNCATE TABLE '.($no_prefix ? '' : $this->prefix).$table_name) ? true : false; + } +} diff --git a/include/dblayer/mysql_innodb.php b/include/dblayer/mysql_innodb.php new file mode 100644 index 0000000..b78c63c --- /dev/null +++ b/include/dblayer/mysql_innodb.php @@ -0,0 +1,363 @@ + 'INT(10) UNSIGNED AUTO_INCREMENT' + ); + + + function DBLayer($db_host, $db_username, $db_password, $db_name, $db_prefix, $p_connect) + { + $this->prefix = $db_prefix; + + if ($p_connect) + $this->link_id = @mysql_pconnect($db_host, $db_username, $db_password); + else + $this->link_id = @mysql_connect($db_host, $db_username, $db_password); + + if ($this->link_id) + { + if (!@mysql_select_db($db_name, $this->link_id)) + error('Unable to select database. MySQL reported: '.mysql_error(), __FILE__, __LINE__); + } + else + error('Unable to connect to MySQL server. MySQL reported: '.mysql_error(), __FILE__, __LINE__); + + // Setup the client-server character set (UTF-8) + if (!defined('FORUM_NO_SET_NAMES')) + $this->set_names('utf8'); + + return $this->link_id; + } + + + function start_transaction() + { + ++$this->in_transaction; + + mysql_query('START TRANSACTION', $this->link_id); + return; + } + + + function end_transaction() + { + --$this->in_transaction; + + mysql_query('COMMIT', $this->link_id); + return; + } + + + function query($sql, $unbuffered = false) + { + if (defined('PUN_SHOW_QUERIES')) + $q_start = get_microtime(); + + if ($unbuffered) + $this->query_result = @mysql_unbuffered_query($sql, $this->link_id); + else + $this->query_result = @mysql_query($sql, $this->link_id); + + if ($this->query_result) + { + if (defined('PUN_SHOW_QUERIES')) + $this->saved_queries[] = array($sql, sprintf('%.5f', get_microtime() - $q_start)); + + ++$this->num_queries; + + return $this->query_result; + } + else + { + if (defined('PUN_SHOW_QUERIES')) + $this->saved_queries[] = array($sql, 0); + + // Rollback transaction + if ($this->in_transaction) + mysql_query('ROLLBACK', $this->link_id); + + --$this->in_transaction; + + return false; + } + } + + + function result($query_id = 0, $row = 0, $col = 0) + { + return ($query_id) ? @mysql_result($query_id, $row, $col) : false; + } + + + function fetch_assoc($query_id = 0) + { + return ($query_id) ? @mysql_fetch_assoc($query_id) : false; + } + + + function fetch_row($query_id = 0) + { + return ($query_id) ? @mysql_fetch_row($query_id) : false; + } + + + function num_rows($query_id = 0) + { + return ($query_id) ? @mysql_num_rows($query_id) : false; + } + + + function affected_rows() + { + return ($this->link_id) ? @mysql_affected_rows($this->link_id) : false; + } + + + function insert_id() + { + return ($this->link_id) ? @mysql_insert_id($this->link_id) : false; + } + + + function get_num_queries() + { + return $this->num_queries; + } + + + function get_saved_queries() + { + return $this->saved_queries; + } + + + function free_result($query_id = false) + { + return ($query_id) ? @mysql_free_result($query_id) : false; + } + + + function escape($str) + { + if (is_array($str)) + return ''; + else if (function_exists('mysql_real_escape_string')) + return mysql_real_escape_string($str, $this->link_id); + else + return mysql_escape_string($str); + } + + + function error() + { + $result['error_sql'] = @current(@end($this->saved_queries)); + $result['error_no'] = @mysql_errno($this->link_id); + $result['error_msg'] = @mysql_error($this->link_id); + + return $result; + } + + + function close() + { + if ($this->link_id) + { + if ($this->query_result) + @mysql_free_result($this->query_result); + + return @mysql_close($this->link_id); + } + else + return false; + } + + + function set_names($names) + { + return $this->query('SET NAMES \''.$this->escape($names).'\''); + } + + + function get_version() + { + $result = $this->query('SELECT VERSION()'); + + return array( + 'name' => 'MySQL Standard (InnoDB)', + 'version' => preg_replace('/^([^-]+).*$/', '\\1', $this->result($result)) + ); + } + + + function table_exists($table_name, $no_prefix = false) + { + $result = $this->query('SHOW TABLES LIKE \''.($no_prefix ? '' : $this->prefix).$this->escape($table_name).'\''); + return $this->num_rows($result) > 0; + } + + + function field_exists($table_name, $field_name, $no_prefix = false) + { + $result = $this->query('SHOW COLUMNS FROM '.($no_prefix ? '' : $this->prefix).$table_name.' LIKE \''.$this->escape($field_name).'\''); + return $this->num_rows($result) > 0; + } + + + function index_exists($table_name, $index_name, $no_prefix = false) + { + $exists = false; + + $result = $this->query('SHOW INDEX FROM '.($no_prefix ? '' : $this->prefix).$table_name); + while ($cur_index = $this->fetch_assoc($result)) + { + if ($cur_index['Key_name'] == ($no_prefix ? '' : $this->prefix).$table_name.'_'.$index_name) + { + $exists = true; + break; + } + } + + return $exists; + } + + + function create_table($table_name, $schema, $no_prefix = false) + { + if ($this->table_exists($table_name, $no_prefix)) + return true; + + $query = 'CREATE TABLE '.($no_prefix ? '' : $this->prefix).$table_name." (\n"; + + // Go through every schema element and add it to the query + foreach ($schema['FIELDS'] as $field_name => $field_data) + { + $field_data['datatype'] = preg_replace(array_keys($this->datatype_transformations), array_values($this->datatype_transformations), $field_data['datatype']); + + $query .= $field_name.' '.$field_data['datatype']; + + if (isset($field_data['collation'])) + $query .= 'CHARACTER SET utf8 COLLATE utf8_'.$field_data['collation']; + + if (!$field_data['allow_null']) + $query .= ' NOT NULL'; + + if (isset($field_data['default'])) + $query .= ' DEFAULT '.$field_data['default']; + + $query .= ",\n"; + } + + // If we have a primary key, add it + if (isset($schema['PRIMARY KEY'])) + $query .= 'PRIMARY KEY ('.implode(',', $schema['PRIMARY KEY']).'),'."\n"; + + // Add unique keys + if (isset($schema['UNIQUE KEYS'])) + { + foreach ($schema['UNIQUE KEYS'] as $key_name => $key_fields) + $query .= 'UNIQUE KEY '.($no_prefix ? '' : $this->prefix).$table_name.'_'.$key_name.'('.implode(',', $key_fields).'),'."\n"; + } + + // Add indexes + if (isset($schema['INDEXES'])) + { + foreach ($schema['INDEXES'] as $index_name => $index_fields) + $query .= 'KEY '.($no_prefix ? '' : $this->prefix).$table_name.'_'.$index_name.'('.implode(',', $index_fields).'),'."\n"; + } + + // We remove the last two characters (a newline and a comma) and add on the ending + $query = substr($query, 0, strlen($query) - 2)."\n".') ENGINE = '.(isset($schema['ENGINE']) ? $schema['ENGINE'] : 'InnoDB').' CHARACTER SET utf8'; + + return $this->query($query) ? true : false; + } + + + function drop_table($table_name, $no_prefix = false) + { + if (!$this->table_exists($table_name, $no_prefix)) + return true; + + return $this->query('DROP TABLE '.($no_prefix ? '' : $this->prefix).$table_name) ? true : false; + } + + + function add_field($table_name, $field_name, $field_type, $allow_null, $default_value = null, $after_field = null, $no_prefix = false) + { + if ($this->field_exists($table_name, $field_name, $no_prefix)) + return true; + + $field_type = preg_replace(array_keys($this->datatype_transformations), array_values($this->datatype_transformations), $field_type); + + if ($default_value !== null && !is_int($default_value) && !is_float($default_value)) + $default_value = '\''.$this->escape($default_value).'\''; + + return $this->query('ALTER TABLE '.($no_prefix ? '' : $this->prefix).$table_name.' ADD '.$field_name.' '.$field_type.($allow_null ? ' ' : ' NOT NULL').($default_value !== null ? ' DEFAULT '.$default_value : ' ').($after_field != null ? ' AFTER '.$after_field : '')) ? true : false; + } + + + function alter_field($table_name, $field_name, $field_type, $allow_null, $default_value = null, $after_field = null, $no_prefix = false) + { + if (!$this->field_exists($table_name, $field_name, $no_prefix)) + return true; + + $field_type = preg_replace(array_keys($this->datatype_transformations), array_values($this->datatype_transformations), $field_type); + + if ($default_value !== null && !is_int($default_value) && !is_float($default_value)) + $default_value = '\''.$this->escape($default_value).'\''; + + return $this->query('ALTER TABLE '.($no_prefix ? '' : $this->prefix).$table_name.' MODIFY '.$field_name.' '.$field_type.($allow_null ? ' ' : ' NOT NULL').($default_value !== null ? ' DEFAULT '.$default_value : ' ').($after_field != null ? ' AFTER '.$after_field : '')) ? true : false; + } + + + function drop_field($table_name, $field_name, $no_prefix = false) + { + if (!$this->field_exists($table_name, $field_name, $no_prefix)) + return true; + + return $this->query('ALTER TABLE '.($no_prefix ? '' : $this->prefix).$table_name.' DROP '.$field_name) ? true : false; + } + + + function add_index($table_name, $index_name, $index_fields, $unique = false, $no_prefix = false) + { + if ($this->index_exists($table_name, $index_name, $no_prefix)) + return true; + + return $this->query('ALTER TABLE '.($no_prefix ? '' : $this->prefix).$table_name.' ADD '.($unique ? 'UNIQUE ' : '').'INDEX '.($no_prefix ? '' : $this->prefix).$table_name.'_'.$index_name.' ('.implode(',', $index_fields).')') ? true : false; + } + + + function drop_index($table_name, $index_name, $no_prefix = false) + { + if (!$this->index_exists($table_name, $index_name, $no_prefix)) + return true; + + return $this->query('ALTER TABLE '.($no_prefix ? '' : $this->prefix).$table_name.' DROP INDEX '.($no_prefix ? '' : $this->prefix).$table_name.'_'.$index_name) ? true : false; + } + + function truncate_table($table_name, $no_prefix = false) + { + return $this->query('TRUNCATE TABLE '.($no_prefix ? '' : $this->prefix).$table_name) ? true : false; + } +} diff --git a/include/dblayer/mysqli.php b/include/dblayer/mysqli.php new file mode 100644 index 0000000..9b81bdd --- /dev/null +++ b/include/dblayer/mysqli.php @@ -0,0 +1,352 @@ + 'INT(10) UNSIGNED AUTO_INCREMENT' + ); + + + function DBLayer($db_host, $db_username, $db_password, $db_name, $db_prefix, $p_connect) + { + $this->prefix = $db_prefix; + + // Was a custom port supplied with $db_host? + if (strpos($db_host, ':') !== false) + list($db_host, $db_port) = explode(':', $db_host); + + // Persistent connection in MySQLi are only available in PHP 5.3 and later releases + $p_connect = $p_connect && version_compare(PHP_VERSION, '5.3.0', '>=') ? 'p:' : ''; + + if (isset($db_port)) + $this->link_id = @mysqli_connect($p_connect.$db_host, $db_username, $db_password, $db_name, $db_port); + else + $this->link_id = @mysqli_connect($p_connect.$db_host, $db_username, $db_password, $db_name); + + if (!$this->link_id) + error('Unable to connect to MySQL and select database. MySQL reported: '.mysqli_connect_error(), __FILE__, __LINE__); + + // Setup the client-server character set (UTF-8) + if (!defined('FORUM_NO_SET_NAMES')) + $this->set_names('utf8'); + + return $this->link_id; + } + + + function start_transaction() + { + return; + } + + + function end_transaction() + { + return; + } + + + function query($sql, $unbuffered = false) + { + if (defined('PUN_SHOW_QUERIES')) + $q_start = get_microtime(); + + $this->query_result = @mysqli_query($this->link_id, $sql); + + if ($this->query_result) + { + if (defined('PUN_SHOW_QUERIES')) + $this->saved_queries[] = array($sql, sprintf('%.5f', get_microtime() - $q_start)); + + ++$this->num_queries; + + return $this->query_result; + } + else + { + if (defined('PUN_SHOW_QUERIES')) + $this->saved_queries[] = array($sql, 0); + + return false; + } + } + + + function result($query_id = 0, $row = 0, $col = 0) + { + if ($query_id) + { + if ($row) + @mysqli_data_seek($query_id, $row); + + $cur_row = @mysqli_fetch_row($query_id); + return $cur_row[$col]; + } + else + return false; + } + + + function fetch_assoc($query_id = 0) + { + return ($query_id) ? @mysqli_fetch_assoc($query_id) : false; + } + + + function fetch_row($query_id = 0) + { + return ($query_id) ? @mysqli_fetch_row($query_id) : false; + } + + + function num_rows($query_id = 0) + { + return ($query_id) ? @mysqli_num_rows($query_id) : false; + } + + + function affected_rows() + { + return ($this->link_id) ? @mysqli_affected_rows($this->link_id) : false; + } + + + function insert_id() + { + return ($this->link_id) ? @mysqli_insert_id($this->link_id) : false; + } + + + function get_num_queries() + { + return $this->num_queries; + } + + + function get_saved_queries() + { + return $this->saved_queries; + } + + + function free_result($query_id = false) + { + return ($query_id) ? @mysqli_free_result($query_id) : false; + } + + + function escape($str) + { + return is_array($str) ? '' : mysqli_real_escape_string($this->link_id, $str); + } + + + function error() + { + $result['error_sql'] = @current(@end($this->saved_queries)); + $result['error_no'] = @mysqli_errno($this->link_id); + $result['error_msg'] = @mysqli_error($this->link_id); + + return $result; + } + + + function close() + { + if ($this->link_id) + { + if ($this->query_result) + @mysqli_free_result($this->query_result); + + return @mysqli_close($this->link_id); + } + else + return false; + } + + function set_names($names) + { + return $this->query('SET NAMES \''.$this->escape($names).'\''); + } + + + function get_version() + { + $result = $this->query('SELECT VERSION()'); + + return array( + 'name' => 'MySQL Improved', + 'version' => preg_replace('/^([^-]+).*$/', '\\1', $this->result($result)) + ); + } + + + function table_exists($table_name, $no_prefix = false) + { + $result = $this->query('SHOW TABLES LIKE \''.($no_prefix ? '' : $this->prefix).$this->escape($table_name).'\''); + return $this->num_rows($result) > 0; + } + + + function field_exists($table_name, $field_name, $no_prefix = false) + { + $result = $this->query('SHOW COLUMNS FROM '.($no_prefix ? '' : $this->prefix).$table_name.' LIKE \''.$this->escape($field_name).'\''); + return $this->num_rows($result) > 0; + } + + + function index_exists($table_name, $index_name, $no_prefix = false) + { + $exists = false; + + $result = $this->query('SHOW INDEX FROM '.($no_prefix ? '' : $this->prefix).$table_name); + while ($cur_index = $this->fetch_assoc($result)) + { + if ($cur_index['Key_name'] == ($no_prefix ? '' : $this->prefix).$table_name.'_'.$index_name) + { + $exists = true; + break; + } + } + + return $exists; + } + + + function create_table($table_name, $schema, $no_prefix = false) + { + if ($this->table_exists($table_name, $no_prefix)) + return true; + + $query = 'CREATE TABLE '.($no_prefix ? '' : $this->prefix).$table_name." (\n"; + + // Go through every schema element and add it to the query + foreach ($schema['FIELDS'] as $field_name => $field_data) + { + $field_data['datatype'] = preg_replace(array_keys($this->datatype_transformations), array_values($this->datatype_transformations), $field_data['datatype']); + + $query .= $field_name.' '.$field_data['datatype']; + + if (isset($field_data['collation'])) + $query .= 'CHARACTER SET utf8 COLLATE utf8_'.$field_data['collation']; + + if (!$field_data['allow_null']) + $query .= ' NOT NULL'; + + if (isset($field_data['default'])) + $query .= ' DEFAULT '.$field_data['default']; + + $query .= ",\n"; + } + + // If we have a primary key, add it + if (isset($schema['PRIMARY KEY'])) + $query .= 'PRIMARY KEY ('.implode(',', $schema['PRIMARY KEY']).'),'."\n"; + + // Add unique keys + if (isset($schema['UNIQUE KEYS'])) + { + foreach ($schema['UNIQUE KEYS'] as $key_name => $key_fields) + $query .= 'UNIQUE KEY '.($no_prefix ? '' : $this->prefix).$table_name.'_'.$key_name.'('.implode(',', $key_fields).'),'."\n"; + } + + // Add indexes + if (isset($schema['INDEXES'])) + { + foreach ($schema['INDEXES'] as $index_name => $index_fields) + $query .= 'KEY '.($no_prefix ? '' : $this->prefix).$table_name.'_'.$index_name.'('.implode(',', $index_fields).'),'."\n"; + } + + // We remove the last two characters (a newline and a comma) and add on the ending + $query = substr($query, 0, strlen($query) - 2)."\n".') ENGINE = '.(isset($schema['ENGINE']) ? $schema['ENGINE'] : 'MyISAM').' CHARACTER SET utf8'; + + return $this->query($query) ? true : false; + } + + + function drop_table($table_name, $no_prefix = false) + { + if (!$this->table_exists($table_name, $no_prefix)) + return true; + + return $this->query('DROP TABLE '.($no_prefix ? '' : $this->prefix).$table_name) ? true : false; + } + + + function add_field($table_name, $field_name, $field_type, $allow_null, $default_value = null, $after_field = null, $no_prefix = false) + { + if ($this->field_exists($table_name, $field_name, $no_prefix)) + return true; + + $field_type = preg_replace(array_keys($this->datatype_transformations), array_values($this->datatype_transformations), $field_type); + + if ($default_value !== null && !is_int($default_value) && !is_float($default_value)) + $default_value = '\''.$this->escape($default_value).'\''; + + return $this->query('ALTER TABLE '.($no_prefix ? '' : $this->prefix).$table_name.' ADD '.$field_name.' '.$field_type.($allow_null ? ' ' : ' NOT NULL').($default_value !== null ? ' DEFAULT '.$default_value : ' ').($after_field != null ? ' AFTER '.$after_field : '')) ? true : false; + } + + + function alter_field($table_name, $field_name, $field_type, $allow_null, $default_value = null, $after_field = null, $no_prefix = false) + { + if (!$this->field_exists($table_name, $field_name, $no_prefix)) + return true; + + $field_type = preg_replace(array_keys($this->datatype_transformations), array_values($this->datatype_transformations), $field_type); + + if ($default_value !== null && !is_int($default_value) && !is_float($default_value)) + $default_value = '\''.$this->escape($default_value).'\''; + + return $this->query('ALTER TABLE '.($no_prefix ? '' : $this->prefix).$table_name.' MODIFY '.$field_name.' '.$field_type.($allow_null ? ' ' : ' NOT NULL').($default_value !== null ? ' DEFAULT '.$default_value : ' ').($after_field != null ? ' AFTER '.$after_field : '')) ? true : false; + } + + + function drop_field($table_name, $field_name, $no_prefix = false) + { + if (!$this->field_exists($table_name, $field_name, $no_prefix)) + return true; + + return $this->query('ALTER TABLE '.($no_prefix ? '' : $this->prefix).$table_name.' DROP '.$field_name) ? true : false; + } + + + function add_index($table_name, $index_name, $index_fields, $unique = false, $no_prefix = false) + { + if ($this->index_exists($table_name, $index_name, $no_prefix)) + return true; + + return $this->query('ALTER TABLE '.($no_prefix ? '' : $this->prefix).$table_name.' ADD '.($unique ? 'UNIQUE ' : '').'INDEX '.($no_prefix ? '' : $this->prefix).$table_name.'_'.$index_name.' ('.implode(',', $index_fields).')') ? true : false; + } + + + function drop_index($table_name, $index_name, $no_prefix = false) + { + if (!$this->index_exists($table_name, $index_name, $no_prefix)) + return true; + + return $this->query('ALTER TABLE '.($no_prefix ? '' : $this->prefix).$table_name.' DROP INDEX '.($no_prefix ? '' : $this->prefix).$table_name.'_'.$index_name) ? true : false; + } + + function truncate_table($table_name, $no_prefix = false) + { + return $this->query('TRUNCATE TABLE '.($no_prefix ? '' : $this->prefix).$table_name) ? true : false; + } +} diff --git a/include/dblayer/mysqli_innodb.php b/include/dblayer/mysqli_innodb.php new file mode 100644 index 0000000..2b591cd --- /dev/null +++ b/include/dblayer/mysqli_innodb.php @@ -0,0 +1,366 @@ + 'INT(10) UNSIGNED AUTO_INCREMENT' + ); + + + function DBLayer($db_host, $db_username, $db_password, $db_name, $db_prefix, $p_connect) + { + $this->prefix = $db_prefix; + + // Was a custom port supplied with $db_host? + if (strpos($db_host, ':') !== false) + list($db_host, $db_port) = explode(':', $db_host); + + // Persistent connection in MySQLi are only available in PHP 5.3 and later releases + $p_connect = $p_connect && version_compare(PHP_VERSION, '5.3.0', '>=') ? 'p:' : ''; + + if (isset($db_port)) + $this->link_id = @mysqli_connect($p_connect.$db_host, $db_username, $db_password, $db_name, $db_port); + else + $this->link_id = @mysqli_connect($p_connect.$db_host, $db_username, $db_password, $db_name); + + if (!$this->link_id) + error('Unable to connect to MySQL and select database. MySQL reported: '.mysqli_connect_error(), __FILE__, __LINE__); + + // Setup the client-server character set (UTF-8) + if (!defined('FORUM_NO_SET_NAMES')) + $this->set_names('utf8'); + + return $this->link_id; + } + + + function start_transaction() + { + ++$this->in_transaction; + + mysqli_query($this->link_id, 'START TRANSACTION'); + return; + } + + + function end_transaction() + { + --$this->in_transaction; + + mysqli_query($this->link_id, 'COMMIT'); + return; + } + + + function query($sql, $unbuffered = false) + { + if (defined('PUN_SHOW_QUERIES')) + $q_start = get_microtime(); + + $this->query_result = @mysqli_query($this->link_id, $sql); + + if ($this->query_result) + { + if (defined('PUN_SHOW_QUERIES')) + $this->saved_queries[] = array($sql, sprintf('%.5f', get_microtime() - $q_start)); + + ++$this->num_queries; + + return $this->query_result; + } + else + { + if (defined('PUN_SHOW_QUERIES')) + $this->saved_queries[] = array($sql, 0); + + // Rollback transaction + if ($this->in_transaction) + mysqli_query($this->link_id, 'ROLLBACK'); + + --$this->in_transaction; + + return false; + } + } + + + function result($query_id = 0, $row = 0, $col = 0) + { + if ($query_id) + { + if ($row) + @mysqli_data_seek($query_id, $row); + + $cur_row = @mysqli_fetch_row($query_id); + return $cur_row[$col]; + } + else + return false; + } + + + function fetch_assoc($query_id = 0) + { + return ($query_id) ? @mysqli_fetch_assoc($query_id) : false; + } + + + function fetch_row($query_id = 0) + { + return ($query_id) ? @mysqli_fetch_row($query_id) : false; + } + + + function num_rows($query_id = 0) + { + return ($query_id) ? @mysqli_num_rows($query_id) : false; + } + + + function affected_rows() + { + return ($this->link_id) ? @mysqli_affected_rows($this->link_id) : false; + } + + + function insert_id() + { + return ($this->link_id) ? @mysqli_insert_id($this->link_id) : false; + } + + + function get_num_queries() + { + return $this->num_queries; + } + + + function get_saved_queries() + { + return $this->saved_queries; + } + + + function free_result($query_id = false) + { + return ($query_id) ? @mysqli_free_result($query_id) : false; + } + + + function escape($str) + { + return is_array($str) ? '' : mysqli_real_escape_string($this->link_id, $str); + } + + + function error() + { + $result['error_sql'] = @current(@end($this->saved_queries)); + $result['error_no'] = @mysqli_errno($this->link_id); + $result['error_msg'] = @mysqli_error($this->link_id); + + return $result; + } + + + function close() + { + if ($this->link_id) + { + if ($this->query_result) + @mysqli_free_result($this->query_result); + + return @mysqli_close($this->link_id); + } + else + return false; + } + + + function set_names($names) + { + return $this->query('SET NAMES \''.$this->escape($names).'\''); + } + + + function get_version() + { + $result = $this->query('SELECT VERSION()'); + + return array( + 'name' => 'MySQL Improved (InnoDB)', + 'version' => preg_replace('/^([^-]+).*$/', '\\1', $this->result($result)) + ); + } + + + function table_exists($table_name, $no_prefix = false) + { + $result = $this->query('SHOW TABLES LIKE \''.($no_prefix ? '' : $this->prefix).$this->escape($table_name).'\''); + return $this->num_rows($result) > 0; + } + + + function field_exists($table_name, $field_name, $no_prefix = false) + { + $result = $this->query('SHOW COLUMNS FROM '.($no_prefix ? '' : $this->prefix).$table_name.' LIKE \''.$this->escape($field_name).'\''); + return $this->num_rows($result) > 0; + } + + + function index_exists($table_name, $index_name, $no_prefix = false) + { + $exists = false; + + $result = $this->query('SHOW INDEX FROM '.($no_prefix ? '' : $this->prefix).$table_name); + while ($cur_index = $this->fetch_assoc($result)) + { + if ($cur_index['Key_name'] == ($no_prefix ? '' : $this->prefix).$table_name.'_'.$index_name) + { + $exists = true; + break; + } + } + + return $exists; + } + + + function create_table($table_name, $schema, $no_prefix = false) + { + if ($this->table_exists($table_name, $no_prefix)) + return true; + + $query = 'CREATE TABLE '.($no_prefix ? '' : $this->prefix).$table_name." (\n"; + + // Go through every schema element and add it to the query + foreach ($schema['FIELDS'] as $field_name => $field_data) + { + $field_data['datatype'] = preg_replace(array_keys($this->datatype_transformations), array_values($this->datatype_transformations), $field_data['datatype']); + + $query .= $field_name.' '.$field_data['datatype']; + + if (isset($field_data['collation'])) + $query .= 'CHARACTER SET utf8 COLLATE utf8_'.$field_data['collation']; + + if (!$field_data['allow_null']) + $query .= ' NOT NULL'; + + if (isset($field_data['default'])) + $query .= ' DEFAULT '.$field_data['default']; + + $query .= ",\n"; + } + + // If we have a primary key, add it + if (isset($schema['PRIMARY KEY'])) + $query .= 'PRIMARY KEY ('.implode(',', $schema['PRIMARY KEY']).'),'."\n"; + + // Add unique keys + if (isset($schema['UNIQUE KEYS'])) + { + foreach ($schema['UNIQUE KEYS'] as $key_name => $key_fields) + $query .= 'UNIQUE KEY '.($no_prefix ? '' : $this->prefix).$table_name.'_'.$key_name.'('.implode(',', $key_fields).'),'."\n"; + } + + // Add indexes + if (isset($schema['INDEXES'])) + { + foreach ($schema['INDEXES'] as $index_name => $index_fields) + $query .= 'KEY '.($no_prefix ? '' : $this->prefix).$table_name.'_'.$index_name.'('.implode(',', $index_fields).'),'."\n"; + } + + // We remove the last two characters (a newline and a comma) and add on the ending + $query = substr($query, 0, strlen($query) - 2)."\n".') ENGINE = '.(isset($schema['ENGINE']) ? $schema['ENGINE'] : 'InnoDB').' CHARACTER SET utf8'; + + return $this->query($query) ? true : false; + } + + + function drop_table($table_name, $no_prefix = false) + { + if (!$this->table_exists($table_name, $no_prefix)) + return true; + + return $this->query('DROP TABLE '.($no_prefix ? '' : $this->prefix).$table_name) ? true : false; + } + + + function add_field($table_name, $field_name, $field_type, $allow_null, $default_value = null, $after_field = null, $no_prefix = false) + { + if ($this->field_exists($table_name, $field_name, $no_prefix)) + return true; + + $field_type = preg_replace(array_keys($this->datatype_transformations), array_values($this->datatype_transformations), $field_type); + + if ($default_value !== null && !is_int($default_value) && !is_float($default_value)) + $default_value = '\''.$this->escape($default_value).'\''; + + return $this->query('ALTER TABLE '.($no_prefix ? '' : $this->prefix).$table_name.' ADD '.$field_name.' '.$field_type.($allow_null ? ' ' : ' NOT NULL').($default_value !== null ? ' DEFAULT '.$default_value : ' ').($after_field != null ? ' AFTER '.$after_field : '')) ? true : false; + } + + + function alter_field($table_name, $field_name, $field_type, $allow_null, $default_value = null, $after_field = null, $no_prefix = false) + { + if (!$this->field_exists($table_name, $field_name, $no_prefix)) + return true; + + $field_type = preg_replace(array_keys($this->datatype_transformations), array_values($this->datatype_transformations), $field_type); + + if ($default_value !== null && !is_int($default_value) && !is_float($default_value)) + $default_value = '\''.$this->escape($default_value).'\''; + + return $this->query('ALTER TABLE '.($no_prefix ? '' : $this->prefix).$table_name.' MODIFY '.$field_name.' '.$field_type.($allow_null ? ' ' : ' NOT NULL').($default_value !== null ? ' DEFAULT '.$default_value : ' ').($after_field != null ? ' AFTER '.$after_field : '')) ? true : false; + } + + + function drop_field($table_name, $field_name, $no_prefix = false) + { + if (!$this->field_exists($table_name, $field_name, $no_prefix)) + return true; + + return $this->query('ALTER TABLE '.($no_prefix ? '' : $this->prefix).$table_name.' DROP '.$field_name) ? true : false; + } + + + function add_index($table_name, $index_name, $index_fields, $unique = false, $no_prefix = false) + { + if ($this->index_exists($table_name, $index_name, $no_prefix)) + return true; + + return $this->query('ALTER TABLE '.($no_prefix ? '' : $this->prefix).$table_name.' ADD '.($unique ? 'UNIQUE ' : '').'INDEX '.($no_prefix ? '' : $this->prefix).$table_name.'_'.$index_name.' ('.implode(',', $index_fields).')') ? true : false; + } + + + function drop_index($table_name, $index_name, $no_prefix = false) + { + if (!$this->index_exists($table_name, $index_name, $no_prefix)) + return true; + + return $this->query('ALTER TABLE '.($no_prefix ? '' : $this->prefix).$table_name.' DROP INDEX '.($no_prefix ? '' : $this->prefix).$table_name.'_'.$index_name) ? true : false; + } + + function truncate_table($table_name, $no_prefix = false) + { + return $this->query('TRUNCATE TABLE '.($no_prefix ? '' : $this->prefix).$table_name) ? true : false; + } +} diff --git a/include/dblayer/pgsql.php b/include/dblayer/pgsql.php new file mode 100644 index 0000000..05d8cf0 --- /dev/null +++ b/include/dblayer/pgsql.php @@ -0,0 +1,427 @@ + 'SMALLINT', + '/^(MEDIUM)?INT( )?(\\([0-9]+\\))?( )?(UNSIGNED)?$/i' => 'INTEGER', + '/^BIGINT( )?(\\([0-9]+\\))?( )?(UNSIGNED)?$/i' => 'BIGINT', + '/^(TINY|MEDIUM|LONG)?TEXT$/i' => 'TEXT', + '/^DOUBLE( )?(\\([0-9,]+\\))?( )?(UNSIGNED)?$/i' => 'DOUBLE PRECISION', + '/^FLOAT( )?(\\([0-9]+\\))?( )?(UNSIGNED)?$/i' => 'REAL' + ); + + + function DBLayer($db_host, $db_username, $db_password, $db_name, $db_prefix, $p_connect) + { + $this->prefix = $db_prefix; + + if ($db_host) + { + if (strpos($db_host, ':') !== false) + { + list($db_host, $dbport) = explode(':', $db_host); + $connect_str[] = 'host='.$db_host.' port='.$dbport; + } + else + $connect_str[] = 'host='.$db_host; + } + + if ($db_name) + $connect_str[] = 'dbname='.$db_name; + + if ($db_username) + $connect_str[] = 'user='.$db_username; + + if ($db_password) + $connect_str[] = 'password='.$db_password; + + if ($p_connect) + $this->link_id = @pg_pconnect(implode(' ', $connect_str)); + else + $this->link_id = @pg_connect(implode(' ', $connect_str)); + + if (!$this->link_id) + error('Unable to connect to PostgreSQL server', __FILE__, __LINE__); + + // Setup the client-server character set (UTF-8) + if (!defined('FORUM_NO_SET_NAMES')) + $this->set_names('utf8'); + + return $this->link_id; + } + + + function start_transaction() + { + ++$this->in_transaction; + + return (@pg_query($this->link_id, 'BEGIN')) ? true : false; + } + + + function end_transaction() + { + --$this->in_transaction; + + if (@pg_query($this->link_id, 'COMMIT')) + return true; + else + { + @pg_query($this->link_id, 'ROLLBACK'); + return false; + } + } + + + function query($sql, $unbuffered = false) // $unbuffered is ignored since there is no pgsql_unbuffered_query() + { + if (strrpos($sql, 'LIMIT') !== false) + $sql = preg_replace('#LIMIT ([0-9]+),([ 0-9]+)#', 'LIMIT \\2 OFFSET \\1', $sql); + + if (defined('PUN_SHOW_QUERIES')) + $q_start = get_microtime(); + + @pg_send_query($this->link_id, $sql); + $this->query_result = @pg_get_result($this->link_id); + + if (pg_result_status($this->query_result) != PGSQL_FATAL_ERROR) + { + if (defined('PUN_SHOW_QUERIES')) + $this->saved_queries[] = array($sql, sprintf('%.5f', get_microtime() - $q_start)); + + ++$this->num_queries; + + $this->last_query_text[$this->query_result] = $sql; + + return $this->query_result; + } + else + { + if (defined('PUN_SHOW_QUERIES')) + $this->saved_queries[] = array($sql, 0); + + $this->error_msg = @pg_result_error($this->query_result); + + if ($this->in_transaction) + @pg_query($this->link_id, 'ROLLBACK'); + + --$this->in_transaction; + + return false; + } + } + + + function result($query_id = 0, $row = 0, $col = 0) + { + return ($query_id) ? @pg_fetch_result($query_id, $row, $col) : false; + } + + + function fetch_assoc($query_id = 0) + { + return ($query_id) ? @pg_fetch_assoc($query_id) : false; + } + + + function fetch_row($query_id = 0) + { + return ($query_id) ? @pg_fetch_row($query_id) : false; + } + + + function num_rows($query_id = 0) + { + return ($query_id) ? @pg_num_rows($query_id) : false; + } + + + function affected_rows() + { + return ($this->query_result) ? @pg_affected_rows($this->query_result) : false; + } + + + function insert_id() + { + $query_id = $this->query_result; + + if ($query_id && $this->last_query_text[$query_id] != '') + { + if (preg_match('/^INSERT INTO ([a-z0-9\_\-]+)/is', $this->last_query_text[$query_id], $table_name)) + { + // Hack (don't ask) + if (substr($table_name[1], -6) == 'groups') + $table_name[1] .= '_g'; + + $temp_q_id = @pg_query($this->link_id, 'SELECT currval(\''.$table_name[1].'_id_seq\')'); + return ($temp_q_id) ? intval(@pg_fetch_result($temp_q_id, 0)) : false; + } + } + + return false; + } + + + function get_num_queries() + { + return $this->num_queries; + } + + + function get_saved_queries() + { + return $this->saved_queries; + } + + + function free_result($query_id = false) + { + if (!$query_id) + $query_id = $this->query_result; + + return ($query_id) ? @pg_free_result($query_id) : false; + } + + + function escape($str) + { + return is_array($str) ? '' : pg_escape_string($str); + } + + + function error() + { + $result['error_sql'] = @current(@end($this->saved_queries)); + $result['error_no'] = false; +/* + if (!empty($this->query_result)) + { + $result['error_msg'] = trim(@pg_result_error($this->query_result)); + if ($result['error_msg'] != '') + return $result; + } + + $result['error_msg'] = (!empty($this->link_id)) ? trim(@pg_last_error($this->link_id)) : trim(@pg_last_error()); +*/ + $result['error_msg'] = $this->error_msg; + + return $result; + } + + + function close() + { + if ($this->link_id) + { + if ($this->in_transaction) + { + if (defined('PUN_SHOW_QUERIES')) + $this->saved_queries[] = array('COMMIT', 0); + + @pg_query($this->link_id, 'COMMIT'); + } + + if ($this->query_result) + @pg_free_result($this->query_result); + + return @pg_close($this->link_id); + } + else + return false; + } + + function set_names($names) + { + return $this->query('SET NAMES \''.$this->escape($names).'\''); + } + + + function get_version() + { + $result = $this->query('SELECT VERSION()'); + + return array( + 'name' => 'PostgreSQL', + 'version' => preg_replace('/^[^0-9]+([^\s,-]+).*$/', '\\1', $this->result($result)) + ); + } + + + function table_exists($table_name, $no_prefix = false) + { + $result = $this->query('SELECT 1 FROM pg_class WHERE relname = \''.($no_prefix ? '' : $this->prefix).$this->escape($table_name).'\''); + return $this->num_rows($result) > 0; + } + + + function field_exists($table_name, $field_name, $no_prefix = false) + { + $result = $this->query('SELECT 1 FROM pg_class c INNER JOIN pg_attribute a ON a.attrelid = c.oid WHERE c.relname = \''.($no_prefix ? '' : $this->prefix).$this->escape($table_name).'\' AND a.attname = \''.$this->escape($field_name).'\''); + return $this->num_rows($result) > 0; + } + + + function index_exists($table_name, $index_name, $no_prefix = false) + { + $result = $this->query('SELECT 1 FROM pg_index i INNER JOIN pg_class c1 ON c1.oid = i.indrelid INNER JOIN pg_class c2 ON c2.oid = i.indexrelid WHERE c1.relname = \''.($no_prefix ? '' : $this->prefix).$this->escape($table_name).'\' AND c2.relname = \''.($no_prefix ? '' : $this->prefix).$this->escape($table_name).'_'.$this->escape($index_name).'\''); + return $this->num_rows($result) > 0; + } + + + function create_table($table_name, $schema, $no_prefix = false) + { + if ($this->table_exists($table_name, $no_prefix)) + return true; + + $query = 'CREATE TABLE '.($no_prefix ? '' : $this->prefix).$table_name." (\n"; + + // Go through every schema element and add it to the query + foreach ($schema['FIELDS'] as $field_name => $field_data) + { + $field_data['datatype'] = preg_replace(array_keys($this->datatype_transformations), array_values($this->datatype_transformations), $field_data['datatype']); + + $query .= $field_name.' '.$field_data['datatype']; + + // The SERIAL datatype is a special case where we don't need to say not null + if (!$field_data['allow_null'] && $field_data['datatype'] != 'SERIAL') + $query .= ' NOT NULL'; + + if (isset($field_data['default'])) + $query .= ' DEFAULT '.$field_data['default']; + + $query .= ",\n"; + } + + // If we have a primary key, add it + if (isset($schema['PRIMARY KEY'])) + $query .= 'PRIMARY KEY ('.implode(',', $schema['PRIMARY KEY']).'),'."\n"; + + // Add unique keys + if (isset($schema['UNIQUE KEYS'])) + { + foreach ($schema['UNIQUE KEYS'] as $key_name => $key_fields) + $query .= 'UNIQUE ('.implode(',', $key_fields).'),'."\n"; + } + + // We remove the last two characters (a newline and a comma) and add on the ending + $query = substr($query, 0, strlen($query) - 2)."\n".')'; + + $result = $this->query($query) ? true : false; + + // Add indexes + if (isset($schema['INDEXES'])) + { + foreach ($schema['INDEXES'] as $index_name => $index_fields) + $result &= $this->add_index($table_name, $index_name, $index_fields, false, $no_prefix); + } + + return $result; + } + + + function drop_table($table_name, $no_prefix = false) + { + if (!$this->table_exists($table_name, $no_prefix)) + return true; + + return $this->query('DROP TABLE '.($no_prefix ? '' : $this->prefix).$table_name) ? true : false; + } + + + function add_field($table_name, $field_name, $field_type, $allow_null, $default_value = null, $after_field = null, $no_prefix = false) + { + if ($this->field_exists($table_name, $field_name, $no_prefix)) + return true; + + $field_type = preg_replace(array_keys($this->datatype_transformations), array_values($this->datatype_transformations), $field_type); + + $result = $this->query('ALTER TABLE '.($no_prefix ? '' : $this->prefix).$table_name.' ADD '.$field_name.' '.$field_type) ? true : false; + + if ($default_value !== null) + { + if (!is_int($default_value) && !is_float($default_value)) + $default_value = '\''.$this->escape($default_value).'\''; + + $result &= $this->query('ALTER TABLE '.($no_prefix ? '' : $this->prefix).$table_name.' ALTER '.$field_name.' SET DEFAULT '.$default_value) ? true : false; + $result &= $this->query('UPDATE '.($no_prefix ? '' : $this->prefix).$table_name.' SET '.$field_name.'='.$default_value) ? true : false; + } + + if (!$allow_null) + $result &= $this->query('ALTER TABLE '.($no_prefix ? '' : $this->prefix).$table_name.' ALTER '.$field_name.' SET NOT NULL') ? true : false; + + return $result; + } + + + function alter_field($table_name, $field_name, $field_type, $allow_null, $default_value = null, $after_field = null, $no_prefix = false) + { + if (!$this->field_exists($table_name, $field_name, $no_prefix)) + return true; + + $field_type = preg_replace(array_keys($this->datatype_transformations), array_values($this->datatype_transformations), $field_type); + + $result = $this->add_field($table_name, 'tmp_'.$field_name, $field_type, $allow_null, $default_value, $after_field, $no_prefix); + $result &= $this->query('UPDATE '.($no_prefix ? '' : $this->prefix).$table_name.' SET tmp_'.$field_name.' = '.$field_name) ? true : false; + $result &= $this->drop_field($table_name, $field_name, $no_prefix); + $result &= $this->query('ALTER TABLE '.($no_prefix ? '' : $this->prefix).$table_name.' RENAME COLUMN tmp_'.$field_name.' TO '.$field_name) ? true : false; + + return $result; + } + + + function drop_field($table_name, $field_name, $no_prefix = false) + { + if (!$this->field_exists($table_name, $field_name, $no_prefix)) + return true; + + return $this->query('ALTER TABLE '.($no_prefix ? '' : $this->prefix).$table_name.' DROP '.$field_name) ? true : false; + } + + + function add_index($table_name, $index_name, $index_fields, $unique = false, $no_prefix = false) + { + if ($this->index_exists($table_name, $index_name, $no_prefix)) + return true; + + return $this->query('CREATE '.($unique ? 'UNIQUE ' : '').'INDEX '.($no_prefix ? '' : $this->prefix).$table_name.'_'.$index_name.' ON '.($no_prefix ? '' : $this->prefix).$table_name.'('.implode(',', $index_fields).')') ? true : false; + } + + + function drop_index($table_name, $index_name, $no_prefix = false) + { + if (!$this->index_exists($table_name, $index_name, $no_prefix)) + return true; + + return $this->query('DROP INDEX '.($no_prefix ? '' : $this->prefix).$table_name.'_'.$index_name) ? true : false; + } + + function truncate_table($table_name, $no_prefix = false) + { + return $this->query('DELETE FROM '.($no_prefix ? '' : $this->prefix).$table_name) ? true : false; + } +} diff --git a/include/dblayer/sqlite.php b/include/dblayer/sqlite.php new file mode 100644 index 0000000..49ffeb8 --- /dev/null +++ b/include/dblayer/sqlite.php @@ -0,0 +1,528 @@ + 'INTEGER', + '/^(TINY|SMALL|MEDIUM|BIG)?INT( )?(\\([0-9]+\\))?( )?(UNSIGNED)?$/i' => 'INTEGER', + '/^(TINY|MEDIUM|LONG)?TEXT$/i' => 'TEXT' + ); + + + function DBLayer($db_host, $db_username, $db_password, $db_name, $db_prefix, $p_connect) + { + // Prepend $db_name with the path to the forum root directory + $db_name = PUN_ROOT.$db_name; + + $this->prefix = $db_prefix; + + if (!file_exists($db_name)) + { + @touch($db_name); + @chmod($db_name, 0666); + if (!file_exists($db_name)) + error('Unable to create new database \''.$db_name.'\'. Permission denied', __FILE__, __LINE__); + } + + if (!is_readable($db_name)) + error('Unable to open database \''.$db_name.'\' for reading. Permission denied', __FILE__, __LINE__); + + if (!is_writable($db_name)) + error('Unable to open database \''.$db_name.'\' for writing. Permission denied', __FILE__, __LINE__); + + if ($p_connect) + $this->link_id = @sqlite_popen($db_name, 0666, $sqlite_error); + else + $this->link_id = @sqlite_open($db_name, 0666, $sqlite_error); + + if (!$this->link_id) + error('Unable to open database \''.$db_name.'\'. SQLite reported: '.$sqlite_error, __FILE__, __LINE__); + else + return $this->link_id; + } + + + function start_transaction() + { + ++$this->in_transaction; + + return (@sqlite_query($this->link_id, 'BEGIN')) ? true : false; + } + + + function end_transaction() + { + --$this->in_transaction; + + if (@sqlite_query($this->link_id, 'COMMIT')) + return true; + else + { + @sqlite_query($this->link_id, 'ROLLBACK'); + return false; + } + } + + + function query($sql, $unbuffered = false) + { + if (defined('PUN_SHOW_QUERIES')) + $q_start = get_microtime(); + + if ($unbuffered) + $this->query_result = @sqlite_unbuffered_query($this->link_id, $sql); + else + $this->query_result = @sqlite_query($this->link_id, $sql); + + if ($this->query_result) + { + if (defined('PUN_SHOW_QUERIES')) + $this->saved_queries[] = array($sql, sprintf('%.5f', get_microtime() - $q_start)); + + ++$this->num_queries; + + return $this->query_result; + } + else + { + if (defined('PUN_SHOW_QUERIES')) + $this->saved_queries[] = array($sql, 0); + + $this->error_no = @sqlite_last_error($this->link_id); + $this->error_msg = @sqlite_error_string($this->error_no); + + if ($this->in_transaction) + @sqlite_query($this->link_id, 'ROLLBACK'); + + --$this->in_transaction; + + return false; + } + } + + + function result($query_id = 0, $row = 0, $col = 0) + { + if ($query_id) + { + if ($row != 0) + @sqlite_seek($query_id, $row); + + $cur_row = @sqlite_current($query_id); + return $cur_row[$col]; + } + else + return false; + } + + + function fetch_assoc($query_id = 0) + { + if ($query_id) + { + $cur_row = @sqlite_fetch_array($query_id, SQLITE_ASSOC); + if ($cur_row) + { + // Horrible hack to get rid of table names and table aliases from the array keys + foreach ($cur_row as $key => $value) + { + $dot_spot = strpos($key, '.'); + if ($dot_spot !== false) + { + unset($cur_row[$key]); + $key = substr($key, $dot_spot+1); + $cur_row[$key] = $value; + } + } + } + + return $cur_row; + } + else + return false; + } + + + function fetch_row($query_id = 0) + { + return ($query_id) ? @sqlite_fetch_array($query_id, SQLITE_NUM) : false; + } + + + function num_rows($query_id = 0) + { + return ($query_id) ? @sqlite_num_rows($query_id) : false; + } + + + function affected_rows() + { + return ($this->query_result) ? @sqlite_changes($this->query_result) : false; + } + + + function insert_id() + { + return ($this->link_id) ? @sqlite_last_insert_rowid($this->link_id) : false; + } + + + function get_num_queries() + { + return $this->num_queries; + } + + + function get_saved_queries() + { + return $this->saved_queries; + } + + + function free_result($query_id = false) + { + return true; + } + + + function escape($str) + { + return is_array($str) ? '' : sqlite_escape_string($str); + } + + + function error() + { + $result['error_sql'] = @current(@end($this->saved_queries)); + $result['error_no'] = $this->error_no; + $result['error_msg'] = $this->error_msg; + + return $result; + } + + + function close() + { + if ($this->link_id) + { + if ($this->in_transaction) + { + if (defined('PUN_SHOW_QUERIES')) + $this->saved_queries[] = array('COMMIT', 0); + + @sqlite_query($this->link_id, 'COMMIT'); + } + + return @sqlite_close($this->link_id); + } + else + return false; + } + + function set_names($names) + { + return; + } + + + function get_version() + { + return array( + 'name' => 'SQLite', + 'version' => sqlite_libversion() + ); + } + + + function table_exists($table_name, $no_prefix = false) + { + $result = $this->query('SELECT 1 FROM sqlite_master WHERE name = \''.($no_prefix ? '' : $this->prefix).$this->escape($table_name).'\' AND type=\'table\''); + return $this->num_rows($result) > 0; + } + + + function field_exists($table_name, $field_name, $no_prefix = false) + { + $result = $this->query('SELECT sql FROM sqlite_master WHERE name = \''.($no_prefix ? '' : $this->prefix).$this->escape($table_name).'\' AND type=\'table\''); + if (!$this->num_rows($result)) + return false; + + return preg_match('/[\r\n]'.preg_quote($field_name).' /', $this->result($result)); + } + + + function index_exists($table_name, $index_name, $no_prefix = false) + { + $result = $this->query('SELECT 1 FROM sqlite_master WHERE tbl_name = \''.($no_prefix ? '' : $this->prefix).$this->escape($table_name).'\' AND name = \''.($no_prefix ? '' : $this->prefix).$this->escape($table_name).'_'.$this->escape($index_name).'\' AND type=\'index\''); + return $this->num_rows($result) > 0; + } + + + function create_table($table_name, $schema, $no_prefix = false) + { + if ($this->table_exists($table_name, $no_prefix)) + return true; + + $query = 'CREATE TABLE '.($no_prefix ? '' : $this->prefix).$table_name." (\n"; + + // Go through every schema element and add it to the query + foreach ($schema['FIELDS'] as $field_name => $field_data) + { + $field_data['datatype'] = preg_replace(array_keys($this->datatype_transformations), array_values($this->datatype_transformations), $field_data['datatype']); + + $query .= $field_name.' '.$field_data['datatype']; + + if (!$field_data['allow_null']) + $query .= ' NOT NULL'; + + if (isset($field_data['default'])) + $query .= ' DEFAULT '.$field_data['default']; + + $query .= ",\n"; + } + + // If we have a primary key, add it + if (isset($schema['PRIMARY KEY'])) + $query .= 'PRIMARY KEY ('.implode(',', $schema['PRIMARY KEY']).'),'."\n"; + + // Add unique keys + if (isset($schema['UNIQUE KEYS'])) + { + foreach ($schema['UNIQUE KEYS'] as $key_name => $key_fields) + $query .= 'UNIQUE ('.implode(',', $key_fields).'),'."\n"; + } + + // We remove the last two characters (a newline and a comma) and add on the ending + $query = substr($query, 0, strlen($query) - 2)."\n".')'; + + $result = $this->query($query) ? true : false; + + // Add indexes + if (isset($schema['INDEXES'])) + { + foreach ($schema['INDEXES'] as $index_name => $index_fields) + $result &= $this->add_index($table_name, $index_name, $index_fields, false, $no_prefix); + } + + return $result; + } + + + function drop_table($table_name, $no_prefix = false) + { + if (!$this->table_exists($table_name, $no_prefix)) + return true; + + return $this->query('DROP TABLE '.($no_prefix ? '' : $this->prefix).$table_name) ? true : false; + } + + + function get_table_info($table_name, $no_prefix = false) + { + // Grab table info + $result = $this->query('SELECT sql FROM sqlite_master WHERE tbl_name = \''.($no_prefix ? '' : $this->prefix).$this->escape($table_name).'\' ORDER BY type DESC') or error('Unable to fetch table information', __FILE__, __LINE__, $this->error()); + $num_rows = $this->num_rows($result); + + if ($num_rows == 0) + return; + + $table = array(); + $table['indices'] = array(); + while ($cur_index = $this->fetch_assoc($result)) + { + if (empty($cur_index['sql'])) + continue; + + if (!isset($table['sql'])) + $table['sql'] = $cur_index['sql']; + else + $table['indices'][] = $cur_index['sql']; + } + + // Work out the columns in the table currently + $table_lines = explode("\n", $table['sql']); + $table['columns'] = array(); + foreach ($table_lines as $table_line) + { + $table_line = pun_trim($table_line); + if (substr($table_line, 0, 12) == 'CREATE TABLE') + continue; + else if (substr($table_line, 0, 11) == 'PRIMARY KEY') + $table['primary_key'] = $table_line; + else if (substr($table_line, 0, 6) == 'UNIQUE') + $table['unique'] = $table_line; + else if (substr($table_line, 0, strpos($table_line, ' ')) != '') + $table['columns'][substr($table_line, 0, strpos($table_line, ' '))] = pun_trim(substr($table_line, strpos($table_line, ' '))); + } + + return $table; + } + + + function add_field($table_name, $field_name, $field_type, $allow_null, $default_value = null, $after_field = 0, $no_prefix = false) + { + if ($this->field_exists($table_name, $field_name, $no_prefix)) + return true; + + $table = $this->get_table_info($table_name, $no_prefix); + + // Create temp table + $now = time(); + $tmptable = str_replace('CREATE TABLE '.($no_prefix ? '' : $this->prefix).$this->escape($table_name).' (', 'CREATE TABLE '.($no_prefix ? '' : $this->prefix).$this->escape($table_name).'_t'.$now.' (', $table['sql']); + $result = $this->query($tmptable) ? true : false; + $result &= $this->query('INSERT INTO '.($no_prefix ? '' : $this->prefix).$this->escape($table_name).'_t'.$now.' SELECT * FROM '.($no_prefix ? '' : $this->prefix).$this->escape($table_name)) ? true : false; + + // Create new table sql + $field_type = preg_replace(array_keys($this->datatype_transformations), array_values($this->datatype_transformations), $field_type); + $query = $field_type; + if (!$allow_null) + $query .= ' NOT NULL'; + if ($default_value === null || $default_value === '') + $default_value = '\'\''; + + $query .= ' DEFAULT '.$default_value; + + $old_columns = array_keys($table['columns']); + array_insert($table['columns'], $after_field, $query.',', $field_name); + + $new_table = 'CREATE TABLE '.($no_prefix ? '' : $this->prefix).$this->escape($table_name).' ('; + + foreach ($table['columns'] as $cur_column => $column_details) + $new_table .= "\n".$cur_column.' '.$column_details; + + if (isset($table['unique'])) + $new_table .= "\n".$table['unique'].','; + + if (isset($table['primary_key'])) + $new_table .= "\n".$table['primary_key']; + + $new_table = trim($new_table, ',')."\n".');'; + + // Drop old table + $result &= $this->drop_table(($no_prefix ? '' : $this->prefix).$this->escape($table_name)); + + // Create new table + $result &= $this->query($new_table) ? true : false; + + // Recreate indexes + if (!empty($table['indices'])) + { + foreach ($table['indices'] as $cur_index) + $result &= $this->query($cur_index) ? true : false; + } + + // Copy content back + $result &= $this->query('INSERT INTO '.($no_prefix ? '' : $this->prefix).$this->escape($table_name).' ('.implode(', ', $old_columns).') SELECT * FROM '.($no_prefix ? '' : $this->prefix).$this->escape($table_name).'_t'.$now) ? true : false; + + // Drop temp table + $result &= $this->drop_table(($no_prefix ? '' : $this->prefix).$this->escape($table_name).'_t'.$now); + + return $result; + } + + + function alter_field($table_name, $field_name, $field_type, $allow_null, $default_value = null, $after_field = 0, $no_prefix = false) + { + // Unneeded for SQLite + return true; + } + + + function drop_field($table_name, $field_name, $no_prefix = false) + { + if (!$this->field_exists($table_name, $field_name, $no_prefix)) + return true; + + $table = $this->get_table_info($table_name, $no_prefix); + + // Create temp table + $now = time(); + $tmptable = str_replace('CREATE TABLE '.($no_prefix ? '' : $this->prefix).$this->escape($table_name).' (', 'CREATE TABLE '.($no_prefix ? '' : $this->prefix).$this->escape($table_name).'_t'.$now.' (', $table['sql']); + $result = $this->query($tmptable) ? true : false; + $result &= $this->query('INSERT INTO '.($no_prefix ? '' : $this->prefix).$this->escape($table_name).'_t'.$now.' SELECT * FROM '.($no_prefix ? '' : $this->prefix).$this->escape($table_name)) ? true : false; + + // Work out the columns we need to keep and the sql for the new table + unset($table['columns'][$field_name]); + $new_columns = array_keys($table['columns']); + + $new_table = 'CREATE TABLE '.($no_prefix ? '' : $this->prefix).$this->escape($table_name).' ('; + + foreach ($table['columns'] as $cur_column => $column_details) + $new_table .= "\n".$cur_column.' '.$column_details; + + if (isset($table['unique'])) + $new_table .= "\n".$table['unique'].','; + + if (isset($table['primary_key'])) + $new_table .= "\n".$table['primary_key']; + + $new_table = trim($new_table, ',')."\n".');'; + + // Drop old table + $result &= $this->drop_table(($no_prefix ? '' : $this->prefix).$this->escape($table_name)); + + // Create new table + $result &= $this->query($new_table) ? true : false; + + // Recreate indexes + if (!empty($table['indices'])) + { + foreach ($table['indices'] as $cur_index) + if (!preg_match('%\('.preg_quote($field_name, '%').'\)%', $cur_index)) + $result &= $this->query($cur_index) ? true : false; + } + + // Copy content back + $result &= $this->query('INSERT INTO '.($no_prefix ? '' : $this->prefix).$this->escape($table_name).' SELECT '.implode(', ', $new_columns).' FROM '.($no_prefix ? '' : $this->prefix).$this->escape($table_name).'_t'.$now) ? true : false; + + // Drop temp table + $result &= $this->drop_table(($no_prefix ? '' : $this->prefix).$this->escape($table_name).'_t'.$now); + + return $result; + } + + + function add_index($table_name, $index_name, $index_fields, $unique = false, $no_prefix = false) + { + if ($this->index_exists($table_name, $index_name, $no_prefix)) + return true; + + return $this->query('CREATE '.($unique ? 'UNIQUE ' : '').'INDEX '.($no_prefix ? '' : $this->prefix).$table_name.'_'.$index_name.' ON '.($no_prefix ? '' : $this->prefix).$table_name.'('.implode(',', $index_fields).')') ? true : false; + } + + + function drop_index($table_name, $index_name, $no_prefix = false) + { + if (!$this->index_exists($table_name, $index_name, $no_prefix)) + return true; + + return $this->query('DROP INDEX '.($no_prefix ? '' : $this->prefix).$table_name.'_'.$index_name) ? true : false; + } + + function truncate_table($table_name, $no_prefix = false) + { + return $this->query('DELETE FROM '.($no_prefix ? '' : $this->prefix).$table_name) ? true : false; + } +} diff --git a/include/email.php b/include/email.php new file mode 100644 index 0000000..86f0660 --- /dev/null +++ b/include/email.php @@ -0,0 +1,186 @@ + 80) + return false; + + return preg_match('/^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|("[^"]+"))@((\[\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\])|(([a-zA-Z\d\-]+\.)+[a-zA-Z]{2,}))$/', $email); +} + + +// +// Check if $email is banned +// +function is_banned_email($email) +{ + global $pun_bans; + + foreach ($pun_bans as $cur_ban) + { + if ($cur_ban['email'] != '' && + ($email == $cur_ban['email'] || + (strpos($cur_ban['email'], '@') === false && stristr($email, '@'.$cur_ban['email'])))) + return true; + } + + return false; +} + + +// +// Wrapper for PHP's mail() +// +function pun_mail($to, $subject, $message, $reply_to_email = '', $reply_to_name = '') +{ + global $pun_config, $lang_common; + + // Default sender/return address + $from_name = str_replace('"', '', $pun_config['o_board_title'].' '.$lang_common['Mailer']); + $from_email = $pun_config['o_webmaster_email']; + + // Do a little spring cleaning + $to = pun_trim(preg_replace('#[\n\r]+#s', '', $to)); + $subject = pun_trim(preg_replace('#[\n\r]+#s', '', $subject)); + $from_email = pun_trim(preg_replace('#[\n\r:]+#s', '', $from_email)); + $from_name = pun_trim(preg_replace('#[\n\r:]+#s', '', str_replace('"', '', $from_name))); + $reply_to_email = pun_trim(preg_replace('#[\n\r:]+#s', '', $reply_to_email)); + $reply_to_name = pun_trim(preg_replace('#[\n\r:]+#s', '', str_replace('"', '', $reply_to_name))); + + // Set up some headers to take advantage of UTF-8 + $from = "=?UTF-8?B?".base64_encode($from_name)."?=".' <'.$from_email.'>'; + $subject = "=?UTF-8?B?".base64_encode($subject)."?="; + + $headers = 'From: '.$from."\r\n".'Date: '.gmdate('r')."\r\n".'MIME-Version: 1.0'."\r\n".'Content-transfer-encoding: 8bit'."\r\n".'Content-type: text/plain; charset=utf-8'."\r\n".'X-Mailer: FluxBB Mailer'; + + // If we specified a reply-to email, we deal with it here + if (!empty($reply_to_email)) + { + $reply_to = "=?UTF-8?B?".base64_encode($reply_to_name)."?=".' <'.$reply_to_email.'>'; + + $headers .= "\r\n".'Reply-To: '.$reply_to; + } + + // Make sure all linebreaks are CRLF in message (and strip out any NULL bytes) + $message = str_replace(array("\n", "\0"), array("\r\n", ''), pun_linebreaks($message)); + + if ($pun_config['o_smtp_host'] != '') + smtp_mail($to, $subject, $message, $headers); + else + { + // Change the linebreaks used in the headers according to OS + if (strtoupper(substr(PHP_OS, 0, 3)) == 'MAC') + $headers = str_replace("\r\n", "\r", $headers); + else if (strtoupper(substr(PHP_OS, 0, 3)) != 'WIN') + $headers = str_replace("\r\n", "\n", $headers); + + mail($to, $subject, $message, $headers); + } +} + + +// +// This function was originally a part of the phpBB Group forum software phpBB2 (http://www.phpbb.com) +// They deserve all the credit for writing it. I made small modifications for it to suit PunBB and it's coding standards +// +function server_parse($socket, $expected_response) +{ + $server_response = ''; + while (substr($server_response, 3, 1) != ' ') + { + if (!($server_response = fgets($socket, 256))) + error('Couldn\'t get mail server response codes. Please contact the forum administrator.', __FILE__, __LINE__); + } + + if (!(substr($server_response, 0, 3) == $expected_response)) + error('Unable to send email. Please contact the forum administrator with the following error message reported by the SMTP server: "'.$server_response.'"', __FILE__, __LINE__); +} + + +// +// This function was originally a part of the phpBB Group forum software phpBB2 (http://www.phpbb.com) +// They deserve all the credit for writing it. I made small modifications for it to suit PunBB and it's coding standards. +// +function smtp_mail($to, $subject, $message, $headers = '') +{ + global $pun_config; + + $recipients = explode(',', $to); + + // Sanitize the message + $message = str_replace("\r\n.", "\r\n..", $message); + $message = (substr($message, 0, 1) == '.' ? '.'.$message : $message); + + // Are we using port 25 or a custom port? + if (strpos($pun_config['o_smtp_host'], ':') !== false) + list($smtp_host, $smtp_port) = explode(':', $pun_config['o_smtp_host']); + else + { + $smtp_host = $pun_config['o_smtp_host']; + $smtp_port = 25; + } + + if ($pun_config['o_smtp_ssl'] == '1') + $smtp_host = 'ssl://'.$smtp_host; + + if (!($socket = fsockopen($smtp_host, $smtp_port, $errno, $errstr, 15))) + error('Could not connect to smtp host "'.$pun_config['o_smtp_host'].'" ('.$errno.') ('.$errstr.')', __FILE__, __LINE__); + + server_parse($socket, '220'); + + if ($pun_config['o_smtp_user'] != '' && $pun_config['o_smtp_pass'] != '') + { + fwrite($socket, 'EHLO '.$smtp_host."\r\n"); + server_parse($socket, '250'); + + fwrite($socket, 'AUTH LOGIN'."\r\n"); + server_parse($socket, '334'); + + fwrite($socket, base64_encode($pun_config['o_smtp_user'])."\r\n"); + server_parse($socket, '334'); + + fwrite($socket, base64_encode($pun_config['o_smtp_pass'])."\r\n"); + server_parse($socket, '235'); + } + else + { + fwrite($socket, 'HELO '.$smtp_host."\r\n"); + server_parse($socket, '250'); + } + + fwrite($socket, 'MAIL FROM: <'.$pun_config['o_webmaster_email'].'>'."\r\n"); + server_parse($socket, '250'); + + foreach ($recipients as $email) + { + fwrite($socket, 'RCPT TO: <'.$email.'>'."\r\n"); + server_parse($socket, '250'); + } + + fwrite($socket, 'DATA'."\r\n"); + server_parse($socket, '354'); + + fwrite($socket, 'Subject: '.$subject."\r\n".'To: <'.implode('>, <', $recipients).'>'."\r\n".$headers."\r\n\r\n".$message."\r\n"); + + fwrite($socket, '.'."\r\n"); + server_parse($socket, '250'); + + fwrite($socket, 'QUIT'."\r\n"); + fclose($socket); + + return true; +} diff --git a/include/functions.php b/include/functions.php new file mode 100644 index 0000000..054e1ed --- /dev/null +++ b/include/functions.php @@ -0,0 +1,1748 @@ + 1, 'password_hash' => 'Guest'); + + // If a cookie is set, we get the user_id and password hash from it + if (isset($_COOKIE[$cookie_name])) + list($cookie['user_id'], $cookie['password_hash'], $cookie['expiration_time']) = @unserialize($_COOKIE[$cookie_name]); + + if ($cookie['user_id'] > 1) + { + // Check if there's a user with the user ID and password hash from the cookie + $result = $db->query('SELECT u.*, g.*, o.logged, o.idle FROM '.$db->prefix.'users AS u INNER JOIN '.$db->prefix.'groups AS g ON u.group_id=g.g_id LEFT JOIN '.$db->prefix.'online AS o ON o.user_id=u.id WHERE u.id='.intval($cookie['user_id'])) or error('Unable to fetch user information', __FILE__, __LINE__, $db->error()); + $pun_user = $db->fetch_assoc($result); + + // If user authorisation failed + if (!isset($pun_user['id']) || md5($cookie_seed.$pun_user['password']) !== $cookie['password_hash']) + { + $expire = $now + 31536000; // The cookie expires after a year + pun_setcookie(1, md5(uniqid(rand(), true)), $expire); + set_default_user(); + + return; + } + + // Send a new, updated cookie with a new expiration timestamp + $expire = (intval($cookie['expiration_time']) > $now + $pun_config['o_timeout_visit']) ? $now + 1209600 : $now + $pun_config['o_timeout_visit']; + pun_setcookie($pun_user['id'], $pun_user['password'], $expire); + + // Set a default language if the user selected language no longer exists + if (!file_exists(PUN_ROOT.'lang/'.$pun_user['language'])) + $pun_user['language'] = $pun_config['o_default_lang']; + + // Set a default style if the user selected style no longer exists + if (!file_exists(PUN_ROOT.'style/'.$pun_user['style'].'.css')) + $pun_user['style'] = $pun_config['o_default_style']; + + if (!$pun_user['disp_topics']) + $pun_user['disp_topics'] = $pun_config['o_disp_topics_default']; + if (!$pun_user['disp_posts']) + $pun_user['disp_posts'] = $pun_config['o_disp_posts_default']; + + // Define this if you want this visit to affect the online list and the users last visit data + if (!defined('PUN_QUIET_VISIT')) + { + // Update the online list + if (!$pun_user['logged']) + { + $pun_user['logged'] = $now; + + // With MySQL/MySQLi/SQLite, REPLACE INTO avoids a user having two rows in the online table + switch ($db_type) + { + case 'mysql': + case 'mysqli': + case 'mysql_innodb': + case 'mysqli_innodb': + case 'sqlite': + $db->query('REPLACE INTO '.$db->prefix.'online (user_id, ident, logged) VALUES('.$pun_user['id'].', \''.$db->escape($pun_user['username']).'\', '.$pun_user['logged'].')') or error('Unable to insert into online list', __FILE__, __LINE__, $db->error()); + break; + + default: + $db->query('INSERT INTO '.$db->prefix.'online (user_id, ident, logged) SELECT '.$pun_user['id'].', \''.$db->escape($pun_user['username']).'\', '.$pun_user['logged'].' WHERE NOT EXISTS (SELECT 1 FROM '.$db->prefix.'online WHERE user_id='.$pun_user['id'].')') or error('Unable to insert into online list', __FILE__, __LINE__, $db->error()); + break; + } + + // Reset tracked topics + set_tracked_topics(null); + } + else + { + // Special case: We've timed out, but no other user has browsed the forums since we timed out + if ($pun_user['logged'] < ($now-$pun_config['o_timeout_visit'])) + { + $db->query('UPDATE '.$db->prefix.'users SET last_visit='.$pun_user['logged'].' WHERE id='.$pun_user['id']) or error('Unable to update user visit data', __FILE__, __LINE__, $db->error()); + $pun_user['last_visit'] = $pun_user['logged']; + } + + $idle_sql = ($pun_user['idle'] == '1') ? ', idle=0' : ''; + $db->query('UPDATE '.$db->prefix.'online SET logged='.$now.$idle_sql.' WHERE user_id='.$pun_user['id']) or error('Unable to update online list', __FILE__, __LINE__, $db->error()); + + // Update tracked topics with the current expire time + if (isset($_COOKIE[$cookie_name.'_track'])) + forum_setcookie($cookie_name.'_track', $_COOKIE[$cookie_name.'_track'], $now + $pun_config['o_timeout_visit']); + } + } + else + { + if (!$pun_user['logged']) + $pun_user['logged'] = $pun_user['last_visit']; + } + + $pun_user['is_guest'] = false; + $pun_user['is_admmod'] = $pun_user['g_id'] == PUN_ADMIN || $pun_user['g_moderator'] == '1'; + } + else + set_default_user(); +} + + +// +// Converts the CDATA end sequence ]]> into ]]> +// +function escape_cdata($str) +{ + return str_replace(']]>', ']]>', $str); +} + + +// +// Authenticates the provided username and password against the user database +// $user can be either a user ID (integer) or a username (string) +// $password can be either a plaintext password or a password hash including salt ($password_is_hash must be set accordingly) +// +function authenticate_user($user, $password, $password_is_hash = false) +{ + global $db, $pun_user; + + // Check if there's a user matching $user and $password + $result = $db->query('SELECT u.*, g.*, o.logged, o.idle FROM '.$db->prefix.'users AS u INNER JOIN '.$db->prefix.'groups AS g ON g.g_id=u.group_id LEFT JOIN '.$db->prefix.'online AS o ON o.user_id=u.id WHERE '.(is_int($user) ? 'u.id='.intval($user) : 'u.username=\''.$db->escape($user).'\'')) or error('Unable to fetch user info', __FILE__, __LINE__, $db->error()); + $pun_user = $db->fetch_assoc($result); + + if (!isset($pun_user['id']) || + ($password_is_hash && $password != $pun_user['password']) || + (!$password_is_hash && pun_hash($password) != $pun_user['password'])) + set_default_user(); + else + $pun_user['is_guest'] = false; +} + + +// +// Try to determine the current URL +// +function get_current_url($max_length = 0) +{ + $protocol = (!isset($_SERVER['HTTPS']) || strtolower($_SERVER['HTTPS']) == 'off') ? 'http://' : 'https://'; + $port = (isset($_SERVER['SERVER_PORT']) && (($_SERVER['SERVER_PORT'] != '80' && $protocol == 'http://') || ($_SERVER['SERVER_PORT'] != '443' && $protocol == 'https://')) && strpos($_SERVER['HTTP_HOST'], ':') === false) ? ':'.$_SERVER['SERVER_PORT'] : ''; + + $url = urldecode($protocol.$_SERVER['HTTP_HOST'].$port.$_SERVER['REQUEST_URI']); + + if (strlen($url) <= $max_length || $max_length == 0) + return $url; + + // We can't find a short enough url + return null; +} + + +// +// Fill $pun_user with default values (for guests) +// +function set_default_user() +{ + global $db, $db_type, $pun_user, $pun_config; + + $remote_addr = get_remote_address(); + + // Fetch guest user + $result = $db->query('SELECT u.*, g.*, o.logged, o.last_post, o.last_search FROM '.$db->prefix.'users AS u INNER JOIN '.$db->prefix.'groups AS g ON u.group_id=g.g_id LEFT JOIN '.$db->prefix.'online AS o ON o.ident=\''.$remote_addr.'\' WHERE u.id=1') or error('Unable to fetch guest information', __FILE__, __LINE__, $db->error()); + if (!$db->num_rows($result)) + exit('Unable to fetch guest information. The table \''.$db->prefix.'users\' must contain an entry with id = 1 that represents anonymous users.'); + + $pun_user = $db->fetch_assoc($result); + + // Update online list + if (!$pun_user['logged']) + { + $pun_user['logged'] = time(); + + // With MySQL/MySQLi/SQLite, REPLACE INTO avoids a user having two rows in the online table + switch ($db_type) + { + case 'mysql': + case 'mysqli': + case 'mysql_innodb': + case 'mysqli_innodb': + case 'sqlite': + $db->query('REPLACE INTO '.$db->prefix.'online (user_id, ident, logged) VALUES(1, \''.$db->escape($remote_addr).'\', '.$pun_user['logged'].')') or error('Unable to insert into online list', __FILE__, __LINE__, $db->error()); + break; + + default: + $db->query('INSERT INTO '.$db->prefix.'online (user_id, ident, logged) SELECT 1, \''.$db->escape($remote_addr).'\', '.$pun_user['logged'].' WHERE NOT EXISTS (SELECT 1 FROM '.$db->prefix.'online WHERE ident=\''.$db->escape($remote_addr).'\')') or error('Unable to insert into online list', __FILE__, __LINE__, $db->error()); + break; + } + } + else + $db->query('UPDATE '.$db->prefix.'online SET logged='.time().' WHERE ident=\''.$db->escape($remote_addr).'\'') or error('Unable to update online list', __FILE__, __LINE__, $db->error()); + + $pun_user['disp_topics'] = $pun_config['o_disp_topics_default']; + $pun_user['disp_posts'] = $pun_config['o_disp_posts_default']; + $pun_user['timezone'] = $pun_config['o_default_timezone']; + $pun_user['dst'] = $pun_config['o_default_dst']; + $pun_user['language'] = $pun_config['o_default_lang']; + $pun_user['style'] = $pun_config['o_default_style']; + $pun_user['is_guest'] = true; + $pun_user['is_admmod'] = false; +} + + +// +// Set a cookie, FluxBB style! +// Wrapper for forum_setcookie +// +function pun_setcookie($user_id, $password_hash, $expire) +{ + global $cookie_name, $cookie_seed; + + forum_setcookie($cookie_name, serialize(array($user_id, md5($cookie_seed.$password_hash), $expire)), $expire); +} + + +// +// Set a cookie, FluxBB style! +// +function forum_setcookie($name, $value, $expire) +{ + global $cookie_path, $cookie_domain, $cookie_secure; + + // Enable sending of a P3P header + header('P3P: CP="CUR ADM"'); + + if (version_compare(PHP_VERSION, '5.2.0', '>=')) + setcookie($name, $value, $expire, $cookie_path, $cookie_domain, $cookie_secure, true); + else + setcookie($name, $value, $expire, $cookie_path.'; HttpOnly', $cookie_domain, $cookie_secure); +} + + +// +// Check whether the connecting user is banned (and delete any expired bans while we're at it) +// +function check_bans() +{ + global $db, $pun_config, $lang_common, $pun_user, $pun_bans; + + // Admins aren't affected + if ($pun_user['g_id'] == PUN_ADMIN || !$pun_bans) + return; + + // Add a dot or a colon (depending on IPv4/IPv6) at the end of the IP address to prevent banned address + // 192.168.0.5 from matching e.g. 192.168.0.50 + $user_ip = get_remote_address(); + $user_ip .= (strpos($user_ip, '.') !== false) ? '.' : ':'; + + $bans_altered = false; + $is_banned = false; + + foreach ($pun_bans as $cur_ban) + { + // Has this ban expired? + if ($cur_ban['expire'] != '' && $cur_ban['expire'] <= time()) + { + $db->query('DELETE FROM '.$db->prefix.'bans WHERE id='.$cur_ban['id']) or error('Unable to delete expired ban', __FILE__, __LINE__, $db->error()); + $bans_altered = true; + continue; + } + + if ($cur_ban['username'] != '' && utf8_strtolower($pun_user['username']) == utf8_strtolower($cur_ban['username'])) + $is_banned = true; + + if ($cur_ban['ip'] != '') + { + $cur_ban_ips = explode(' ', $cur_ban['ip']); + + $num_ips = count($cur_ban_ips); + for ($i = 0; $i < $num_ips; ++$i) + { + // Add the proper ending to the ban + if (strpos($user_ip, '.') !== false) + $cur_ban_ips[$i] = $cur_ban_ips[$i].'.'; + else + $cur_ban_ips[$i] = $cur_ban_ips[$i].':'; + + if (substr($user_ip, 0, strlen($cur_ban_ips[$i])) == $cur_ban_ips[$i]) + { + $is_banned = true; + break; + } + } + } + + if ($is_banned) + { + $db->query('DELETE FROM '.$db->prefix.'online WHERE ident=\''.$db->escape($pun_user['username']).'\'') or error('Unable to delete from online list', __FILE__, __LINE__, $db->error()); + message($lang_common['Ban message'].' '.(($cur_ban['expire'] != '') ? $lang_common['Ban message 2'].' '.strtolower(format_time($cur_ban['expire'], true)).'. ' : '').(($cur_ban['message'] != '') ? $lang_common['Ban message 3'].'

    '.pun_htmlspecialchars($cur_ban['message']).'

    ' : '

    ').$lang_common['Ban message 4'].' '.$pun_config['o_admin_email'].'.', true); + } + } + + // If we removed any expired bans during our run-through, we need to regenerate the bans cache + if ($bans_altered) + { + if (!defined('FORUM_CACHE_FUNCTIONS_LOADED')) + require PUN_ROOT.'include/cache.php'; + + generate_bans_cache(); + } +} + + +// +// Check username +// +function check_username($username, $exclude_id = null) +{ + global $db, $pun_config, $errors, $lang_prof_reg, $lang_register, $lang_common, $pun_bans; + + // Convert multiple whitespace characters into one (to prevent people from registering with indistinguishable usernames) + $username = preg_replace('#\s+#s', ' ', $username); + + // Validate username + if (pun_strlen($username) < 2) + $errors[] = $lang_prof_reg['Username too short']; + else if (pun_strlen($username) > 25) // This usually doesn't happen since the form element only accepts 25 characters + $errors[] = $lang_prof_reg['Username too long']; + else if (!strcasecmp($username, 'Guest') || !strcasecmp($username, $lang_common['Guest'])) + $errors[] = $lang_prof_reg['Username guest']; + else if (preg_match('/[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}/', $username) || preg_match('/((([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}:[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){5}:([0-9A-Fa-f]{1,4}:)?[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){4}:([0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){3}:([0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){2}:([0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|(([0-9A-Fa-f]{1,4}:){0,5}:((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|(::([0-9A-Fa-f]{1,4}:){0,5}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|([0-9A-Fa-f]{1,4}::([0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})|(::([0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){1,7}:))/', $username)) + $errors[] = $lang_prof_reg['Username IP']; + else if ((strpos($username, '[') !== false || strpos($username, ']') !== false) && strpos($username, '\'') !== false && strpos($username, '"') !== false) + $errors[] = $lang_prof_reg['Username reserved chars']; + else if (preg_match('/(?:\[\/?(?:b|u|s|ins|del|em|i|h|colou?r|quote|code|img|url|email|list|\*)\]|\[(?:img|url|quote|list)=)/i', $username)) + $errors[] = $lang_prof_reg['Username BBCode']; + + // Check username for any censored words + if ($pun_config['o_censoring'] == '1' && censor_words($username) != $username) + $errors[] = $lang_register['Username censor']; + + // Check that the username (or a too similar username) is not already registered + $query = ($exclude_id) ? ' AND id!='.$exclude_id : ''; + + $result = $db->query('SELECT username FROM '.$db->prefix.'users WHERE (UPPER(username)=UPPER(\''.$db->escape($username).'\') OR UPPER(username)=UPPER(\''.$db->escape(preg_replace('/[^\w]/', '', $username)).'\')) AND id>1'.$query) or error('Unable to fetch user info', __FILE__, __LINE__, $db->error()); + + if ($db->num_rows($result)) + { + $busy = $db->result($result); + $errors[] = $lang_register['Username dupe 1'].' '.pun_htmlspecialchars($busy).'. '.$lang_register['Username dupe 2']; + } + + // Check username for any banned usernames + foreach ($pun_bans as $cur_ban) + { + if ($cur_ban['username'] != '' && utf8_strtolower($username) == utf8_strtolower($cur_ban['username'])) + { + $errors[] = $lang_prof_reg['Banned username']; + break; + } + } +} + + +// +// Update "Users online" +// +function update_users_online() +{ + global $db, $pun_config; + + $now = time(); + + // Fetch all online list entries that are older than "o_timeout_online" + $result = $db->query('SELECT user_id, ident, logged, idle FROM '.$db->prefix.'online WHERE logged<'.($now-$pun_config['o_timeout_online'])) or error('Unable to fetch old entries from online list', __FILE__, __LINE__, $db->error()); + while ($cur_user = $db->fetch_assoc($result)) + { + // If the entry is a guest, delete it + if ($cur_user['user_id'] == '1') + $db->query('DELETE FROM '.$db->prefix.'online WHERE ident=\''.$db->escape($cur_user['ident']).'\'') or error('Unable to delete from online list', __FILE__, __LINE__, $db->error()); + else + { + // If the entry is older than "o_timeout_visit", update last_visit for the user in question, then delete him/her from the online list + if ($cur_user['logged'] < ($now-$pun_config['o_timeout_visit'])) + { + $db->query('UPDATE '.$db->prefix.'users SET last_visit='.$cur_user['logged'].' WHERE id='.$cur_user['user_id']) or error('Unable to update user visit data', __FILE__, __LINE__, $db->error()); + $db->query('DELETE FROM '.$db->prefix.'online WHERE user_id='.$cur_user['user_id']) or error('Unable to delete from online list', __FILE__, __LINE__, $db->error()); + } + else if ($cur_user['idle'] == '0') + $db->query('UPDATE '.$db->prefix.'online SET idle=1 WHERE user_id='.$cur_user['user_id']) or error('Unable to insert into online list', __FILE__, __LINE__, $db->error()); + } + } +} + + +// +// Generate the "navigator" that appears at the top of every page +// +function generate_navlinks() +{ + global $pun_config, $lang_common, $pun_user; + + // Index and Userlist should always be displayed + $links[] = ''; + + if ($pun_user['g_read_board'] == '1' && $pun_user['g_view_users'] == '1') + $links[] = ''; + + if ($pun_config['o_rules'] == '1' && (!$pun_user['is_guest'] || $pun_user['g_read_board'] == '1' || $pun_config['o_regs_allow'] == '1')) + $links[] = ''; + + if ($pun_user['is_guest']) + { + if ($pun_user['g_read_board'] == '1' && $pun_user['g_search'] == '1') + $links[] = ''; + + $links[] = ''; + $links[] = ''; + } + else + { + if (!$pun_user['is_admmod']) + { + if ($pun_user['g_read_board'] == '1' && $pun_user['g_search'] == '1') + $links[] = ''; + + $links[] = ''; + $links[] = ''; + } + else + { + $links[] = ''; + $links[] = ''; + $links[] = ''; + $links[] = ''; + } + } + + // Are there any additional navlinks we should insert into the array before imploding it? + if ($pun_config['o_additional_navlinks'] != '') + { + if (preg_match_all('#([0-9]+)\s*=\s*(.*?)\n#s', $pun_config['o_additional_navlinks']."\n", $extra_links)) + { + // Insert any additional links into the $links array (at the correct index) + $num_links = count($extra_links[1]); + for ($i = 0; $i < $num_links; ++$i) + array_splice($links, $extra_links[1][$i], 0, array('')); + } + } + + return '
      '."\n\t\t\t\t".implode("\n\t\t\t\t", $links)."\n\t\t\t".'
    '; +} + + +// +// Display the profile navigation menu +// +function generate_profile_menu($page = '') +{ + global $lang_profile, $pun_config, $pun_user, $id; + +?> +
    +
    +

    +
    +
    +
      + > + > + > + > + > + > + > +
    +
    +
    +
    +'; + break; + } + } + + return $avatar_markup; +} + + +// +// Generate browser's title +// +function generate_page_title($page_title, $p = null) +{ + global $pun_config, $lang_common; + + $page_title = array_reverse($page_title); + + if ($p != null) + $page_title[0] .= ' ('.sprintf($lang_common['Page'], forum_number_format($p)).')'; + + $crumbs = implode($lang_common['Title separator'], $page_title); + + return $crumbs; +} + + +// +// Save array of tracked topics in cookie +// +function set_tracked_topics($tracked_topics) +{ + global $cookie_name, $cookie_path, $cookie_domain, $cookie_secure, $pun_config; + + $cookie_data = ''; + if (!empty($tracked_topics)) + { + // Sort the arrays (latest read first) + arsort($tracked_topics['topics'], SORT_NUMERIC); + arsort($tracked_topics['forums'], SORT_NUMERIC); + + // Homebrew serialization (to avoid having to run unserialize() on cookie data) + foreach ($tracked_topics['topics'] as $id => $timestamp) + $cookie_data .= 't'.$id.'='.$timestamp.';'; + foreach ($tracked_topics['forums'] as $id => $timestamp) + $cookie_data .= 'f'.$id.'='.$timestamp.';'; + + // Enforce a 4048 byte size limit (4096 minus some space for the cookie name) + if (strlen($cookie_data) > 4048) + { + $cookie_data = substr($cookie_data, 0, 4048); + $cookie_data = substr($cookie_data, 0, strrpos($cookie_data, ';')).';'; + } + } + + forum_setcookie($cookie_name.'_track', $cookie_data, time() + $pun_config['o_timeout_visit']); + $_COOKIE[$cookie_name.'_track'] = $cookie_data; // Set it directly in $_COOKIE as well +} + + +// +// Extract array of tracked topics from cookie +// +function get_tracked_topics() +{ + global $cookie_name; + + $cookie_data = isset($_COOKIE[$cookie_name.'_track']) ? $_COOKIE[$cookie_name.'_track'] : false; + if (!$cookie_data) + return array('topics' => array(), 'forums' => array()); + + if (strlen($cookie_data) > 4048) + return array('topics' => array(), 'forums' => array()); + + // Unserialize data from cookie + $tracked_topics = array('topics' => array(), 'forums' => array()); + $temp = explode(';', $cookie_data); + foreach ($temp as $t) + { + $type = substr($t, 0, 1) == 'f' ? 'forums' : 'topics'; + $id = intval(substr($t, 1)); + $timestamp = intval(substr($t, strpos($t, '=') + 1)); + if ($id > 0 && $timestamp > 0) + $tracked_topics[$type][$id] = $timestamp; + } + + return $tracked_topics; +} + + +// +// Update posts, topics, last_post, last_post_id and last_poster for a forum +// +function update_forum($forum_id) +{ + global $db; + + $result = $db->query('SELECT COUNT(id), SUM(num_replies) FROM '.$db->prefix.'topics WHERE forum_id='.$forum_id) or error('Unable to fetch forum topic count', __FILE__, __LINE__, $db->error()); + list($num_topics, $num_posts) = $db->fetch_row($result); + + $num_posts = $num_posts + $num_topics; // $num_posts is only the sum of all replies (we have to add the topic posts) + + $result = $db->query('SELECT last_post, last_post_id, last_poster FROM '.$db->prefix.'topics WHERE forum_id='.$forum_id.' AND moved_to IS NULL ORDER BY last_post DESC LIMIT 1') or error('Unable to fetch last_post/last_post_id/last_poster', __FILE__, __LINE__, $db->error()); + if ($db->num_rows($result)) // There are topics in the forum + { + list($last_post, $last_post_id, $last_poster) = $db->fetch_row($result); + + $db->query('UPDATE '.$db->prefix.'forums SET num_topics='.$num_topics.', num_posts='.$num_posts.', last_post='.$last_post.', last_post_id='.$last_post_id.', last_poster=\''.$db->escape($last_poster).'\' WHERE id='.$forum_id) or error('Unable to update last_post/last_post_id/last_poster', __FILE__, __LINE__, $db->error()); + } + else // There are no topics + $db->query('UPDATE '.$db->prefix.'forums SET num_topics='.$num_topics.', num_posts='.$num_posts.', last_post=NULL, last_post_id=NULL, last_poster=NULL WHERE id='.$forum_id) or error('Unable to update last_post/last_post_id/last_poster', __FILE__, __LINE__, $db->error()); +} + + +// +// Deletes any avatars owned by the specified user ID +// +function delete_avatar($user_id) +{ + global $pun_config; + + $filetypes = array('jpg', 'gif', 'png'); + + // Delete user avatar + foreach ($filetypes as $cur_type) + { + if (file_exists(PUN_ROOT.$pun_config['o_avatars_dir'].'/'.$user_id.'.'.$cur_type)) + @unlink(PUN_ROOT.$pun_config['o_avatars_dir'].'/'.$user_id.'.'.$cur_type); + } +} + + +// +// Delete a topic and all of it's posts +// +function delete_topic($topic_id) +{ + global $db; + + // Delete the topic and any redirect topics + $db->query('DELETE FROM '.$db->prefix.'topics WHERE id='.$topic_id.' OR moved_to='.$topic_id) or error('Unable to delete topic', __FILE__, __LINE__, $db->error()); + + // Create a list of the post IDs in this topic + $post_ids = ''; + $result = $db->query('SELECT id FROM '.$db->prefix.'posts WHERE topic_id='.$topic_id) or error('Unable to fetch posts', __FILE__, __LINE__, $db->error()); + while ($row = $db->fetch_row($result)) + $post_ids .= ($post_ids != '') ? ','.$row[0] : $row[0]; + + // Make sure we have a list of post IDs + if ($post_ids != '') + { + strip_search_index($post_ids); + + // Delete posts in topic + $db->query('DELETE FROM '.$db->prefix.'posts WHERE topic_id='.$topic_id) or error('Unable to delete posts', __FILE__, __LINE__, $db->error()); + } + + // Delete any subscriptions for this topic + $db->query('DELETE FROM '.$db->prefix.'subscriptions WHERE topic_id='.$topic_id) or error('Unable to delete subscriptions', __FILE__, __LINE__, $db->error()); +} + + +// +// Delete a single post +// +function delete_post($post_id, $topic_id) +{ + global $db; + + $result = $db->query('SELECT id, poster, posted FROM '.$db->prefix.'posts WHERE topic_id='.$topic_id.' ORDER BY id DESC LIMIT 2') or error('Unable to fetch post info', __FILE__, __LINE__, $db->error()); + list($last_id, ,) = $db->fetch_row($result); + list($second_last_id, $second_poster, $second_posted) = $db->fetch_row($result); + + // Delete the post + $db->query('DELETE FROM '.$db->prefix.'posts WHERE id='.$post_id) or error('Unable to delete post', __FILE__, __LINE__, $db->error()); + + strip_search_index($post_id); + + // Count number of replies in the topic + $result = $db->query('SELECT COUNT(id) FROM '.$db->prefix.'posts WHERE topic_id='.$topic_id) or error('Unable to fetch post count for topic', __FILE__, __LINE__, $db->error()); + $num_replies = $db->result($result, 0) - 1; + + // If the message we deleted is the most recent in the topic (at the end of the topic) + if ($last_id == $post_id) + { + // If there is a $second_last_id there is more than 1 reply to the topic + if (!empty($second_last_id)) + $db->query('UPDATE '.$db->prefix.'topics SET last_post='.$second_posted.', last_post_id='.$second_last_id.', last_poster=\''.$db->escape($second_poster).'\', num_replies='.$num_replies.' WHERE id='.$topic_id) or error('Unable to update topic', __FILE__, __LINE__, $db->error()); + else + // We deleted the only reply, so now last_post/last_post_id/last_poster is posted/id/poster from the topic itself + $db->query('UPDATE '.$db->prefix.'topics SET last_post=posted, last_post_id=id, last_poster=poster, num_replies='.$num_replies.' WHERE id='.$topic_id) or error('Unable to update topic', __FILE__, __LINE__, $db->error()); + } + else + // Otherwise we just decrement the reply counter + $db->query('UPDATE '.$db->prefix.'topics SET num_replies='.$num_replies.' WHERE id='.$topic_id) or error('Unable to update topic', __FILE__, __LINE__, $db->error()); +} + + +// +// Delete every .php file in the forum's cache directory +// +function forum_clear_cache() +{ + $d = dir(FORUM_CACHE_DIR); + while (($entry = $d->read()) !== false) + { + if (substr($entry, -4) == '.php') + @unlink(FORUM_CACHE_DIR.$entry); + } + $d->close(); +} + + +// +// Replace censored words in $text +// +function censor_words($text) +{ + global $db; + static $search_for, $replace_with; + + // If not already built in a previous call, build an array of censor words and their replacement text + if (!isset($search_for)) + { + $result = $db->query('SELECT search_for, replace_with FROM '.$db->prefix.'censoring') or error('Unable to fetch censor word list', __FILE__, __LINE__, $db->error()); + $num_words = $db->num_rows($result); + + $search_for = array(); + for ($i = 0; $i < $num_words; ++$i) + { + list($search_for[$i], $replace_with[$i]) = $db->fetch_row($result); + $search_for[$i] = '/\b('.str_replace('\*', '\w*?', preg_quote($search_for[$i], '/')).')\b/i'; + } + } + + if (!empty($search_for)) + $text = substr(preg_replace($search_for, $replace_with, ' '.$text.' '), 1, -1); + + return $text; +} + + +// +// Determines the correct title for $user +// $user must contain the elements 'username', 'title', 'posts', 'g_id' and 'g_user_title' +// +function get_title($user) +{ + global $db, $pun_config, $pun_bans, $lang_common; + static $ban_list, $pun_ranks; + + // If not already built in a previous call, build an array of lowercase banned usernames + if (empty($ban_list)) + { + $ban_list = array(); + + foreach ($pun_bans as $cur_ban) + $ban_list[] = strtolower($cur_ban['username']); + } + + // If not already loaded in a previous call, load the cached ranks + if ($pun_config['o_ranks'] == '1' && empty($pun_ranks)) + { + if (file_exists(FORUM_CACHE_DIR.'cache_ranks.php')) + include FORUM_CACHE_DIR.'cache_ranks.php'; + + if (!defined('PUN_RANKS_LOADED')) + { + if (!defined('FORUM_CACHE_FUNCTIONS_LOADED')) + require PUN_ROOT.'include/cache.php'; + + generate_ranks_cache(); + require FORUM_CACHE_DIR.'cache_ranks.php'; + } + } + + // If the user has a custom title + if ($user['title'] != '') + $user_title = pun_htmlspecialchars($user['title']); + // If the user is banned + else if (in_array(strtolower($user['username']), $ban_list)) + $user_title = $lang_common['Banned']; + // If the user group has a default user title + else if ($user['g_user_title'] != '') + $user_title = pun_htmlspecialchars($user['g_user_title']); + // If the user is a guest + else if ($user['g_id'] == PUN_GUEST) + $user_title = $lang_common['Guest']; + else + { + // Are there any ranks? + if ($pun_config['o_ranks'] == '1' && !empty($pun_ranks)) + { + foreach ($pun_ranks as $cur_rank) + { + if (intval($user['num_posts']) >= $cur_rank['min_posts']) + $user_title = pun_htmlspecialchars($cur_rank['rank']); + } + } + + // If the user didn't "reach" any rank (or if ranks are disabled), we assign the default + if (!isset($user_title)) + $user_title = $lang_common['Member']; + } + + return $user_title; +} + + +// +// Generate a string with numbered links (for multipage scripts) +// +function paginate($num_pages, $cur_page, $link) +{ + global $lang_common; + + $pages = array(); + $link_to_all = false; + + // If $cur_page == -1, we link to all pages (used in viewforum.php) + if ($cur_page == -1) + { + $cur_page = 1; + $link_to_all = true; + } + + if ($num_pages <= 1) + $pages = array('1'); + else + { + // Add a previous page link + if ($num_pages > 1 && $cur_page > 1) + $pages[] = ''.$lang_common['Previous'].''; + + if ($cur_page > 3) + { + $pages[] = '1'; + + if ($cur_page > 5) + $pages[] = ''.$lang_common['Spacer'].''; + } + + // Don't ask me how the following works. It just does, OK? :-) + for ($current = ($cur_page == 5) ? $cur_page - 3 : $cur_page - 2, $stop = ($cur_page + 4 == $num_pages) ? $cur_page + 4 : $cur_page + 3; $current < $stop; ++$current) + { + if ($current < 1 || $current > $num_pages) + continue; + else if ($current != $cur_page || $link_to_all) + $pages[] = ''.forum_number_format($current).''; + else + $pages[] = ''.forum_number_format($current).''; + } + + if ($cur_page <= ($num_pages-3)) + { + if ($cur_page != ($num_pages-3) && $cur_page != ($num_pages-4)) + $pages[] = ''.$lang_common['Spacer'].''; + + $pages[] = ''.forum_number_format($num_pages).''; + } + + // Add a next page link + if ($num_pages > 1 && !$link_to_all && $cur_page < $num_pages) + $pages[] = ''.$lang_common['Next'].''; + } + + return implode(' ', $pages); +} + + +// +// Display a message +// +function message($message, $no_back_link = false) +{ + global $db, $lang_common, $pun_config, $pun_start, $tpl_main; + + if (!defined('PUN_HEADER')) + { + global $pun_user; + + $page_title = array(pun_htmlspecialchars($pun_config['o_board_title']), $lang_common['Info']); + define('PUN_ACTIVE_PAGE', 'index'); + require PUN_ROOT.'header.php'; + } + +?> + +
    +

    +
    +
    +

    +

    +
    +
    +
    + count($input)) + $offset = count($input); + else if ($offset < 0) + $offset = 0; + + $input = array_merge(array_slice($input, 0, $offset), array($key => $element), array_slice($input, $offset)); +} + + +// +// Display a message when board is in maintenance mode +// +function maintenance_message() +{ + global $db, $pun_config, $lang_common, $pun_user; + + // Deal with newlines, tabs and multiple spaces + $pattern = array("\t", ' ', ' '); + $replace = array('    ', '  ', '  '); + $message = str_replace($pattern, $replace, $pun_config['o_maintenance_message']); + + + if (file_exists(PUN_ROOT.'style/'.$pun_user['style'].'/maintenance.tpl')) + { + $tpl_file = PUN_ROOT.'style/'.$pun_user['style'].'/maintenance.tpl'; + $tpl_inc_dir = PUN_ROOT.'style/'.$pun_user['style'].'/'; + } + else + { + $tpl_file = PUN_ROOT.'include/template/maintenance.tpl'; + $tpl_inc_dir = PUN_ROOT.'include/user/'; + } + + $tpl_maint = file_get_contents($tpl_file); + + // START SUBST - + preg_match_all('##', $tpl_maint, $pun_includes, PREG_SET_ORDER); + + foreach ($pun_includes as $cur_include) + { + ob_start(); + + // Allow for overriding user includes, too. + if (file_exists($tpl_inc_dir.$cur_include[1].'.'.$cur_include[2])) + require $tpl_inc_dir.$cur_include[1].'.'.$cur_include[2]; + else if (file_exists(PUN_ROOT.'include/user/'.$cur_include[1].'.'.$cur_include[2])) + require PUN_ROOT.'include/user/'.$cur_include[1].'.'.$cur_include[2]; + else + error(sprintf($lang_common['Pun include error'], htmlspecialchars($cur_include[0]), basename($tpl_file))); + + $tpl_temp = ob_get_contents(); + $tpl_maint = str_replace($cur_include[0], $tpl_temp, $tpl_maint); + ob_end_clean(); + } + // END SUBST - + + + // START SUBST - + $tpl_maint = str_replace('', $lang_common['lang_identifier'], $tpl_maint); + // END SUBST - + + + // START SUBST - + $tpl_maint = str_replace('', $lang_common['lang_direction'], $tpl_maint); + // END SUBST - + + + // START SUBST - + ob_start(); + + $page_title = array(pun_htmlspecialchars($pun_config['o_board_title']), $lang_common['Maintenance']); + +?> +<?php echo generate_page_title($page_title) ?> + +', $tpl_temp, $tpl_maint); + ob_end_clean(); + // END SUBST - + + + // START SUBST - + ob_start(); + +?> +
    +

    +
    +
    +

    +
    +
    +
    +', $tpl_temp, $tpl_maint); + ob_end_clean(); + // END SUBST - + + + // End the transaction + $db->end_transaction(); + + + // Close the db connection (and free up any result data) + $db->close(); + + exit($tpl_maint); +} + + +// +// Display $message and redirect user to $destination_url +// +function redirect($destination_url, $message) +{ + global $db, $pun_config, $lang_common, $pun_user; + + // Prefix with o_base_url (unless there's already a valid URI) + if (strpos($destination_url, 'http://') !== 0 && strpos($destination_url, 'https://') !== 0 && strpos($destination_url, '/') !== 0) + $destination_url = $pun_config['o_base_url'].'/'.$destination_url; + + // Do a little spring cleaning + $destination_url = preg_replace('/([\r\n])|(%0[ad])|(;\s*data\s*:)/i', '', $destination_url); + + // If the delay is 0 seconds, we might as well skip the redirect all together + if ($pun_config['o_redirect_delay'] == '0') + header('Location: '.str_replace('&', '&', $destination_url)); + + // Send no-cache headers + header('Expires: Thu, 21 Jul 1977 07:30:00 GMT'); // When yours truly first set eyes on this world! :) + header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT'); + header('Cache-Control: post-check=0, pre-check=0', false); + header('Pragma: no-cache'); // For HTTP/1.0 compatibility + + // Send the Content-type header in case the web server is setup to send something else + header('Content-type: text/html; charset=utf-8'); + + if (file_exists(PUN_ROOT.'style/'.$pun_user['style'].'/redirect.tpl')) + { + $tpl_file = PUN_ROOT.'style/'.$pun_user['style'].'/redirect.tpl'; + $tpl_inc_dir = PUN_ROOT.'style/'.$pun_user['style'].'/'; + } + else + { + $tpl_file = PUN_ROOT.'include/template/redirect.tpl'; + $tpl_inc_dir = PUN_ROOT.'include/user/'; + } + + $tpl_redir = file_get_contents($tpl_file); + + // START SUBST - + preg_match_all('##', $tpl_redir, $pun_includes, PREG_SET_ORDER); + + foreach ($pun_includes as $cur_include) + { + ob_start(); + + // Allow for overriding user includes, too. + if (file_exists($tpl_inc_dir.$cur_include[1].'.'.$cur_include[2])) + require $tpl_inc_dir.$cur_include[1].'.'.$cur_include[2]; + else if (file_exists(PUN_ROOT.'include/user/'.$cur_include[1].'.'.$cur_include[2])) + require PUN_ROOT.'include/user/'.$cur_include[1].'.'.$cur_include[2]; + else + error(sprintf($lang_common['Pun include error'], htmlspecialchars($cur_include[0]), basename($tpl_file))); + + $tpl_temp = ob_get_contents(); + $tpl_redir = str_replace($cur_include[0], $tpl_temp, $tpl_redir); + ob_end_clean(); + } + // END SUBST - + + + // START SUBST - + $tpl_redir = str_replace('', $lang_common['lang_identifier'], $tpl_redir); + // END SUBST - + + + // START SUBST - + $tpl_redir = str_replace('', $lang_common['lang_direction'], $tpl_redir); + // END SUBST - + + + // START SUBST - + ob_start(); + + $page_title = array(pun_htmlspecialchars($pun_config['o_board_title']), $lang_common['Redirecting']); + +?> +" /> +<?php echo generate_page_title($page_title) ?> + +', $tpl_temp, $tpl_redir); + ob_end_clean(); + // END SUBST - + + + // START SUBST - + ob_start(); + +?> + +', $tpl_temp, $tpl_redir); + ob_end_clean(); + // END SUBST - + + + // START SUBST - + ob_start(); + + // End the transaction + $db->end_transaction(); + + // Display executed queries (if enabled) + if (defined('PUN_SHOW_QUERIES')) + display_saved_queries(); + + $tpl_temp = trim(ob_get_contents()); + $tpl_redir = str_replace('', $tpl_temp, $tpl_redir); + ob_end_clean(); + // END SUBST - + + + // Close the db connection (and free up any result data) + $db->close(); + + exit($tpl_redir); +} + + +// +// Display a simple error message +// +function error($message, $file = null, $line = null, $db_error = false) +{ + global $pun_config, $lang_common; + + // Set some default settings if the script failed before $pun_config could be populated + if (empty($pun_config)) + { + $pun_config = array( + 'o_board_title' => 'FluxBB', + 'o_gzip' => '0' + ); + } + + // Set some default translations if the script failed before $lang_common could be populated + if (empty($lang_common)) + { + $lang_common = array( + 'Title separator' => ' / ', + 'Page' => 'Page %s' + ); + } + + // Empty all output buffers and stop buffering + while (@ob_end_clean()); + + // "Restart" output buffering if we are using ob_gzhandler (since the gzip header is already sent) + if ($pun_config['o_gzip'] && extension_loaded('zlib')) + ob_start('ob_gzhandler'); + + // Send no-cache headers + header('Expires: Thu, 21 Jul 1977 07:30:00 GMT'); // When yours truly first set eyes on this world! :) + header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT'); + header('Cache-Control: post-check=0, pre-check=0', false); + header('Pragma: no-cache'); // For HTTP/1.0 compatibility + + // Send the Content-type header in case the web server is setup to send something else + header('Content-type: text/html; charset=utf-8'); + +?> + + + + + +<?php echo generate_page_title($page_title) ?> + + + + +
    +

    An error was encountered

    +
    +File: '.$file.'
    '."\n\t\t".'Line: '.$line.'

    '."\n\t\t".'FluxBB reported: '.$message."\n"; + + if ($db_error) + { + echo "\t\t".'

    Database reported: '.pun_htmlspecialchars($db_error['error_msg']).(($db_error['error_no']) ? ' (Errno: '.$db_error['error_no'].')' : '')."\n"; + + if ($db_error['error_sql'] != '') + echo "\t\t".'

    Failed query: '.pun_htmlspecialchars($db_error['error_sql'])."\n"; + } + } + else + echo "\t\t".'Error: '.$message.'.'."\n"; + +?> +
    +
    + + + +close(); + + exit; +} + + +// +// Unset any variables instantiated as a result of register_globals being enabled +// +function forum_unregister_globals() +{ + $register_globals = ini_get('register_globals'); + if ($register_globals === '' || $register_globals === '0' || strtolower($register_globals) === 'off') + return; + + // Prevent script.php?GLOBALS[foo]=bar + if (isset($_REQUEST['GLOBALS']) || isset($_FILES['GLOBALS'])) + exit('I\'ll have a steak sandwich and... a steak sandwich.'); + + // Variables that shouldn't be unset + $no_unset = array('GLOBALS', '_GET', '_POST', '_COOKIE', '_REQUEST', '_SERVER', '_ENV', '_FILES'); + + // Remove elements in $GLOBALS that are present in any of the superglobals + $input = array_merge($_GET, $_POST, $_COOKIE, $_SERVER, $_ENV, $_FILES, isset($_SESSION) && is_array($_SESSION) ? $_SESSION : array()); + foreach ($input as $k => $v) + { + if (!in_array($k, $no_unset) && isset($GLOBALS[$k])) + { + unset($GLOBALS[$k]); + unset($GLOBALS[$k]); // Double unset to circumvent the zend_hash_del_key_or_index hole in PHP <4.4.3 and <5.1.4 + } + } +} + + +// +// Removes any "bad" characters (characters which mess with the display of a page, are invisible, etc) from user input +// +function forum_remove_bad_characters() +{ + $_GET = remove_bad_characters($_GET); + $_POST = remove_bad_characters($_POST); + $_COOKIE = remove_bad_characters($_COOKIE); + $_REQUEST = remove_bad_characters($_REQUEST); +} + +// +// Removes any "bad" characters (characters which mess with the display of a page, are invisible, etc) from the given string +// See: http://kb.mozillazine.org/Network.IDN.blacklist_chars +// +function remove_bad_characters($array) +{ + static $bad_utf8_chars; + + if (!isset($bad_utf8_chars)) + { + $bad_utf8_chars = array( + "\xcc\xb7" => '', // COMBINING SHORT SOLIDUS OVERLAY 0337 * + "\xcc\xb8" => '', // COMBINING LONG SOLIDUS OVERLAY 0338 * + "\xe1\x85\x9F" => '', // HANGUL CHOSEONG FILLER 115F * + "\xe1\x85\xA0" => '', // HANGUL JUNGSEONG FILLER 1160 * + "\xe2\x80\x8b" => '', // ZERO WIDTH SPACE 200B * + "\xe2\x80\x8c" => '', // ZERO WIDTH NON-JOINER 200C + "\xe2\x80\x8d" => '', // ZERO WIDTH JOINER 200D + "\xe2\x80\x8e" => '', // LEFT-TO-RIGHT MARK 200E + "\xe2\x80\x8f" => '', // RIGHT-TO-LEFT MARK 200F + "\xe2\x80\xaa" => '', // LEFT-TO-RIGHT EMBEDDING 202A + "\xe2\x80\xab" => '', // RIGHT-TO-LEFT EMBEDDING 202B + "\xe2\x80\xac" => '', // POP DIRECTIONAL FORMATTING 202C + "\xe2\x80\xad" => '', // LEFT-TO-RIGHT OVERRIDE 202D + "\xe2\x80\xae" => '', // RIGHT-TO-LEFT OVERRIDE 202E + "\xe2\x80\xaf" => '', // NARROW NO-BREAK SPACE 202F * + "\xe2\x81\x9f" => '', // MEDIUM MATHEMATICAL SPACE 205F * + "\xe2\x81\xa0" => '', // WORD JOINER 2060 + "\xe3\x85\xa4" => '', // HANGUL FILLER 3164 * + "\xef\xbb\xbf" => '', // ZERO WIDTH NO-BREAK SPACE FEFF + "\xef\xbe\xa0" => '', // HALFWIDTH HANGUL FILLER FFA0 * + "\xef\xbf\xb9" => '', // INTERLINEAR ANNOTATION ANCHOR FFF9 * + "\xef\xbf\xba" => '', // INTERLINEAR ANNOTATION SEPARATOR FFFA * + "\xef\xbf\xbb" => '', // INTERLINEAR ANNOTATION TERMINATOR FFFB * + "\xef\xbf\xbc" => '', // OBJECT REPLACEMENT CHARACTER FFFC * + "\xef\xbf\xbd" => '', // REPLACEMENT CHARACTER FFFD * + "\xc2\xad" => '-', // SOFT HYPHEN 00AD + "\xE2\x80\x9C" => '"', // LEFT DOUBLE QUOTATION MARK 201C + "\xE2\x80\x9D" => '"', // RIGHT DOUBLE QUOTATION MARK 201D + "\xE2\x80\x98" => '\'', // LEFT SINGLE QUOTATION MARK 2018 + "\xE2\x80\x99" => '\'', // RIGHT SINGLE QUOTATION MARK 2019 + "\xe2\x80\x80" => ' ', // EN QUAD 2000 * + "\xe2\x80\x81" => ' ', // EM QUAD 2001 * + "\xe2\x80\x82" => ' ', // EN SPACE 2002 * + "\xe2\x80\x83" => ' ', // EM SPACE 2003 * + "\xe2\x80\x84" => ' ', // THREE-PER-EM SPACE 2004 * + "\xe2\x80\x85" => ' ', // FOUR-PER-EM SPACE 2005 * + "\xe2\x80\x86" => ' ', // SIX-PER-EM SPACE 2006 * + "\xe2\x80\x87" => ' ', // FIGURE SPACE 2007 * + "\xe2\x80\x88" => ' ', // PUNCTUATION SPACE 2008 * + "\xe2\x80\x89" => ' ', // THIN SPACE 2009 * + "\xe2\x80\x8a" => ' ', // HAIR SPACE 200A * + "\xE3\x80\x80" => ' ', // IDEOGRAPHIC SPACE 3000 * + ); + } + + if (is_array($array)) + return array_map('remove_bad_characters', $array); + + // Strip out any invalid characters + $array = utf8_bad_strip($array); + + // Remove control characters + $array = preg_replace('/[\x{00}-\x{08}\x{0b}-\x{0c}\x{0e}-\x{1f}]/', '', $array); + + // Replace some "bad" characters + $array = str_replace(array_keys($bad_utf8_chars), array_values($bad_utf8_chars), $array); + + return $array; +} + + +// +// Converts the file size in bytes to a human readable file size +// +function file_size($size) +{ + $units = array('B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB'); + + for ($i = 0; $size > 1024; $i++) + $size /= 1024; + + return round($size, 2).' '.$units[$i]; +} + + +// +// Fetch a list of available styles +// +function forum_list_styles() +{ + $styles = array(); + + $d = dir(PUN_ROOT.'style'); + while (($entry = $d->read()) !== false) + { + if ($entry{0} == '.') + continue; + + if (substr($entry, -4) == '.css') + $styles[] = substr($entry, 0, -4); + } + $d->close(); + + natcasesort($styles); + + return $styles; +} + + +// +// Fetch a list of available language packs +// +function forum_list_langs() +{ + $languages = array(); + + $d = dir(PUN_ROOT.'lang'); + while (($entry = $d->read()) !== false) + { + if ($entry{0} == '.') + continue; + + if (is_dir(PUN_ROOT.'lang/'.$entry) && file_exists(PUN_ROOT.'lang/'.$entry.'/common.php')) + $languages[] = $entry; + } + $d->close(); + + natcasesort($languages); + + return $languages; +} + + +// +// Fetch a list of available admin plugins +// +function forum_list_plugins($is_admin) +{ + $plugins = array(); + + $d = dir(PUN_ROOT.'plugins'); + while (($entry = $d->read()) !== false) + { + if ($entry{0} == '.') + continue; + + $prefix = substr($entry, 0, strpos($entry, '_')); + $suffix = substr($entry, strlen($entry) - 4); + + if ($suffix == '.php' && ((!$is_admin && $prefix == 'AMP') || ($is_admin && ($prefix == 'AP' || $prefix == 'AMP')))) + $plugins[] = array(substr($entry, strpos($entry, '_') + 1, -4), $entry); + } + $d->close(); + + natcasesort($plugins); + + return $plugins; +} + +// DEBUG FUNCTIONS BELOW + +// +// Display executed queries (if enabled) +// +function display_saved_queries() +{ + global $db, $lang_common; + + // Get the queries so that we can print them out + $saved_queries = $db->get_saved_queries(); + +?> + +
    +

    +
    +
    + + + + + + + + + + + + + + + + + + +
    +
    +
    +
    +'; + + $num_args = func_num_args(); + + for ($i = 0; $i < $num_args; ++$i) + { + print_r(func_get_arg($i)); + echo "\n\n"; + } + + echo ''; + exit; +} diff --git a/include/index.html b/include/index.html new file mode 100644 index 0000000..89337b2 --- /dev/null +++ b/include/index.html @@ -0,0 +1 @@ +.. diff --git a/include/parser.php b/include/parser.php new file mode 100644 index 0000000..a6fceab --- /dev/null +++ b/include/parser.php @@ -0,0 +1,932 @@ + 'smile.png', + '=)' => 'smile.png', + ':|' => 'neutral.png', + '=|' => 'neutral.png', + ':(' => 'sad.png', + '=(' => 'sad.png', + ':D' => 'big_smile.png', + '=D' => 'big_smile.png', + ':o' => 'yikes.png', + ':O' => 'yikes.png', + ';)' => 'wink.png', + ':/' => 'hmm.png', + ':P' => 'tongue.png', + ':p' => 'tongue.png', + ':lol:' => 'lol.png', + ':mad:' => 'mad.png', + ':rolleyes:' => 'roll.png', + ':cool:' => 'cool.png'); + +// +// Make sure all BBCodes are lower case and do a little cleanup +// +function preparse_bbcode($text, &$errors, $is_signature = false) +{ + global $pun_config, $lang_common, $re_list; + + if ($is_signature) + { + global $lang_profile; + + if (preg_match('%\[/?(?:quote|code|list|h)\b[^\]]*\]%i', $text)) + $errors[] = $lang_profile['Signature quote/code/list/h']; + } + + // If the message contains a code tag we have to split it up (text within [code][/code] shouldn't be touched) + if (strpos($text, '[code]') !== false && strpos($text, '[/code]') !== false) + { + list($inside, $outside) = split_text($text, '[code]', '[/code]', $errors); + $text = implode("\1", $outside); + } + + // Tidy up lists + $temp = preg_replace($re_list, 'preparse_list_tag(\'$2\', \'$1\', $errors)', $text); + + // If the regex failed + if ($temp === null) + $errors[] = $lang_common['BBCode list size error']; + else + $text = str_replace('*'."\0".']', '*]', $temp); + + if ($pun_config['o_make_links'] == '1') + $text = do_clickable($text); + + // If we split up the message before we have to concatenate it together again (code tags) + if (isset($inside)) + { + $outside = explode("\1", $text); + $text = ''; + + $num_tokens = count($outside); + + for ($i = 0; $i < $num_tokens; ++$i) + { + $text .= $outside[$i]; + if (isset($inside[$i])) + $text .= '[code]'.$inside[$i].'[/code]'; + } + } + unset($inside); + + $temp_text = false; + if (empty($errors)) + $temp_text = preparse_tags($text, $errors, $is_signature); + + if ($temp_text !== false) + $text = $temp_text; + + // Remove empty tags + while (($new_text = strip_empty_bbcode($text, $errors)) !== false) + { + if ($new_text != $text) + $text = $new_text; + else + break; + } + + return pun_trim($text); +} + + +// +// Strip empty bbcode tags from some text +// +function strip_empty_bbcode($text, &$errors) +{ + // If the message contains a code tag we have to split it up (empty tags within [code][/code] are fine) + if (strpos($text, '[code]') !== false && strpos($text, '[/code]') !== false) + { + list($inside, $outside) = split_text($text, '[code]', '[/code]', $errors); + $text = implode("\1", $outside); + } + + // Remove empty tags + while (($new_text = preg_replace('/\[(b|u|s|ins|del|em|i|h|colou?r|quote|img|url|email|list)(?:\=[^\]]*)?\]\s*\[\/\1\]/', '', $text)) !== false) + { + if ($new_text != $text) + $text = $new_text; + else + break; + } + + // If we split up the message before we have to concatenate it together again (code tags) + if (isset($inside)) + { + $outside = explode("\1", $text); + $text = ''; + + $num_tokens = count($outside); + for ($i = 0; $i < $num_tokens; ++$i) + { + $text .= $outside[$i]; + if (isset($inside[$i])) + $text .= '[code]'.$inside[$i].'[/code]'; + } + } + + // Remove empty code tags + while (($new_text = preg_replace('/\[(code)\]\s*\[\/\1\]/', '', $text)) !== false) + { + if ($new_text != $text) + $text = $new_text; + else + break; + } + + return $text; +} + + +// +// Check the structure of bbcode tags and fix simple mistakes where possible +// +function preparse_tags($text, &$errors, $is_signature = false) +{ + global $lang_common, $pun_config; + + // Start off by making some arrays of bbcode tags and what we need to do with each one + + // List of all the tags + $tags = array('quote', 'code', 'b', 'i', 'u', 's', 'ins', 'del', 'em', 'color', 'colour', 'url', 'email', 'img', 'list', '*', 'h'); + // List of tags that we need to check are open (You could not put b,i,u in here then illegal nesting like [b][i][/b][/i] would be allowed) + $tags_opened = $tags; + // and tags we need to check are closed (the same as above, added it just in case) + $tags_closed = $tags; + // Tags we can nest and the depth they can be nested to (only quotes) + $tags_nested = array('quote' => $pun_config['o_quote_depth'], 'list' => 5, '*' => 5); + // Tags to ignore the contents of completely (just code) + $tags_ignore = array('code'); + // Block tags, block tags can only go within another block tag, they cannot be in a normal tag + $tags_block = array('quote', 'code', 'list', 'h', '*'); + // Inline tags, we do not allow new lines in these + $tags_inline = array('b', 'i', 'u', 's', 'ins', 'del', 'em', 'color', 'colour', 'h'); + // Tags we trim interior space + $tags_trim = array('img'); + // Tags we remove quotes from the argument + $tags_quotes = array('url', 'email', 'img'); + // Tags we limit bbcode in + $tags_limit_bbcode = array( + '*' => array('b', 'i', 'u', 's', 'ins', 'del', 'em', 'color', 'colour', 'url', 'email', 'list', 'img', 'code'), + 'list' => array('*'), + 'url' => array('b', 'i', 'u', 's', 'ins', 'del', 'em', 'color', 'colour', 'img'), + 'email' => array('b', 'i', 'u', 's', 'ins', 'del', 'em', 'color', 'colour', 'img'), + 'img' => array(), + 'h' => array('b', 'i', 'u', 's', 'ins', 'del', 'em', 'color', 'colour', 'url', 'email'), + ); + // Tags we can automatically fix bad nesting + $tags_fix = array('quote', 'b', 'i', 'u', 's', 'ins', 'del', 'em', 'color', 'colour', 'url', 'email', 'h'); + + $split_text = preg_split("/(\[[\*a-zA-Z0-9-\/]*?(?:=.*?)?\])/", $text, -1, PREG_SPLIT_DELIM_CAPTURE|PREG_SPLIT_NO_EMPTY); + + $open_tags = array('post'); + $open_args = array(''); + $opened_tag = 0; + $new_text = ''; + $current_ignore = ''; + $current_nest = ''; + $current_depth = array(); + $limit_bbcode = $tags; + + foreach ($split_text as $current) + { + if ($current == '') + continue; + + // Are we dealing with a tag? + if (substr($current, 0, 1) != '[' || substr($current, -1, 1) != ']') + { + // It's not a bbcode tag so we put it on the end and continue + + // If we are nested too deeply don't add to the end + if ($current_nest) + continue; + + $current = str_replace("\r\n", "\n", $current); + $current = str_replace("\r", "\n", $current); + if (in_array($open_tags[$opened_tag], $tags_inline) && strpos($current, "\n") !== false) + { + // Deal with new lines + $split_current = preg_split("/(\n\n+)/", $current, -1, PREG_SPLIT_DELIM_CAPTURE|PREG_SPLIT_NO_EMPTY); + $current = ''; + + if (!pun_trim($split_current[0], "\n")) // The first part is a linebreak so we need to handle any open tags first + array_unshift($split_current, ''); + + for ($i = 1; $i < count($split_current); $i += 2) + { + $temp_opened = array(); + $temp_opened_arg = array(); + $temp = $split_current[$i - 1]; + while (!empty($open_tags)) + { + $temp_tag = array_pop($open_tags); + $temp_arg = array_pop($open_args); + + if (in_array($temp_tag , $tags_inline)) + { + array_push($temp_opened, $temp_tag); + array_push($temp_opened_arg, $temp_arg); + $temp .= '[/'.$temp_tag.']'; + } + else + { + array_push($open_tags, $temp_tag); + array_push($open_args, $temp_arg); + break; + } + } + $current .= $temp.$split_current[$i]; + $temp = ''; + while (!empty($temp_opened)) + { + $temp_tag = array_pop($temp_opened); + $temp_arg = array_pop($temp_opened_arg); + if (empty($temp_arg)) + $temp .= '['.$temp_tag.']'; + else + $temp .= '['.$temp_tag.'='.$temp_arg.']'; + array_push($open_tags, $temp_tag); + array_push($open_args, $temp_arg); + } + $current .= $temp; + } + + if (array_key_exists($i - 1, $split_current)) + $current .= $split_current[$i - 1]; + } + + if (in_array($open_tags[$opened_tag], $tags_trim)) + $new_text .= pun_trim($current); + else + $new_text .= $current; + + continue; + } + + // Get the name of the tag + $current_arg = ''; + if (strpos($current, '/') === 1) + { + $current_tag = substr($current, 2, -1); + } + else if (strpos($current, '=') === false) + { + $current_tag = substr($current, 1, -1); + } + else + { + $current_tag = substr($current, 1, strpos($current, '=')-1); + $current_arg = substr($current, strpos($current, '=')+1, -1); + } + $current_tag = strtolower($current_tag); + + // Is the tag defined? + if (!in_array($current_tag, $tags)) + { + // It's not a bbcode tag so we put it on the end and continue + if (!$current_nest) + $new_text .= $current; + + continue; + } + + // We definitely have a bbcode tag + + // Make the tag string lower case + if ($equalpos = strpos($current,'=')) + { + // We have an argument for the tag which we don't want to make lowercase + if (strlen(substr($current, $equalpos)) == 2) + { + // Empty tag argument + $errors[] = sprintf($lang_common['BBCode error empty attribute'], $current_tag); + return false; + } + $current = strtolower(substr($current, 0, $equalpos)).substr($current, $equalpos); + } + else + $current = strtolower($current); + + // This is if we are currently in a tag which escapes other bbcode such as code + if ($current_ignore) + { + if ('[/'.$current_ignore.']' == $current) + { + // We've finished the ignored section + $current = '[/'.$current_tag.']'; + $current_ignore = ''; + } + + $new_text .= $current; + + continue; + } + + if ($current_nest) + { + // We are currently too deeply nested so lets see if we are closing the tag or not + if ($current_tag != $current_nest) + continue; + + if (substr($current, 1, 1) == '/') + $current_depth[$current_nest]--; + else + $current_depth[$current_nest]++; + + if ($current_depth[$current_nest] <= $tags_nested[$current_nest]) + $current_nest = ''; + + continue; + } + + // Check the current tag is allowed here + if (!in_array($current_tag, $limit_bbcode) && $current_tag != $open_tags[$opened_tag]) + { + $errors[] = sprintf($lang_common['BBCode error invalid nesting'], $current_tag, $open_tags[$opened_tag]); + return false; + } + + if (substr($current, 1, 1) == '/') + { + // This is if we are closing a tag + + if ($opened_tag == 0 || !in_array($current_tag, $open_tags)) + { + // We tried to close a tag which is not open + if (in_array($current_tag, $tags_opened)) + { + $errors[] = sprintf($lang_common['BBCode error no opening tag'], $current_tag); + return false; + } + } + else + { + // Check nesting + while (true) + { + // Nesting is ok + if ($open_tags[$opened_tag] == $current_tag) + { + array_pop($open_tags); + array_pop($open_args); + $opened_tag--; + break; + } + + // Nesting isn't ok, try to fix it + if (in_array($open_tags[$opened_tag], $tags_closed) && in_array($current_tag, $tags_closed)) + { + if (in_array($current_tag, $open_tags)) + { + $temp_opened = array(); + $temp_opened_arg = array(); + $temp = ''; + while (!empty($open_tags)) + { + $temp_tag = array_pop($open_tags); + $temp_arg = array_pop($open_args); + + if (!in_array($temp_tag, $tags_fix)) + { + // We couldn't fix nesting + $errors[] = sprintf($lang_common['BBCode error no closing tag'], array_pop($temp_opened)); + return false; + } + array_push($temp_opened, $temp_tag); + array_push($temp_opened_arg, $temp_arg); + + if ($temp_tag == $current_tag) + break; + else + $temp .= '[/'.$temp_tag.']'; + } + $current = $temp.$current; + $temp = ''; + array_pop($temp_opened); + array_pop($temp_opened_arg); + + while (!empty($temp_opened)) + { + $temp_tag = array_pop($temp_opened); + $temp_arg = array_pop($temp_opened_arg); + if (empty($temp_arg)) + $temp .= '['.$temp_tag.']'; + else + $temp .= '['.$temp_tag.'='.$temp_arg.']'; + array_push($open_tags, $temp_tag); + array_push($open_args, $temp_arg); + } + $current .= $temp; + $opened_tag--; + break; + } + else + { + // We couldn't fix nesting + $errors[] = sprintf($lang_common['BBCode error no opening tag'], $current_tag); + return false; + } + } + else if (in_array($open_tags[$opened_tag], $tags_closed)) + break; + else + { + array_pop($open_tags); + array_pop($open_args); + $opened_tag--; + } + } + } + + if (in_array($current_tag, array_keys($tags_nested))) + { + if (isset($current_depth[$current_tag])) + $current_depth[$current_tag]--; + } + + if (in_array($open_tags[$opened_tag], array_keys($tags_limit_bbcode))) + $limit_bbcode = $tags_limit_bbcode[$open_tags[$opened_tag]]; + else + $limit_bbcode = $tags; + + $new_text .= $current; + + continue; + } + else + { + // We are opening a tag + if (in_array($current_tag, array_keys($tags_limit_bbcode))) + $limit_bbcode = $tags_limit_bbcode[$current_tag]; + else + $limit_bbcode = $tags; + + if (in_array($current_tag, $tags_block) && !in_array($open_tags[$opened_tag], $tags_block) && $opened_tag != 0) + { + // We tried to open a block tag within a non-block tag + $errors[] = sprintf($lang_common['BBCode error invalid nesting'], $current_tag, $open_tags[$opened_tag]); + return false; + } + + if (in_array($current_tag, $tags_ignore)) + { + // It's an ignore tag so we don't need to worry about what's inside it + $current_ignore = $current_tag; + $new_text .= $current; + continue; + } + + // Deal with nested tags + if (in_array($current_tag, $open_tags) && !in_array($current_tag, array_keys($tags_nested))) + { + // We nested a tag we shouldn't + $errors[] = sprintf($lang_common['BBCode error invalid self-nesting'], $current_tag); + return false; + } + else if (in_array($current_tag, array_keys($tags_nested))) + { + // We are allowed to nest this tag + + if (isset($current_depth[$current_tag])) + $current_depth[$current_tag]++; + else + $current_depth[$current_tag] = 1; + + // See if we are nested too deep + if ($current_depth[$current_tag] > $tags_nested[$current_tag]) + { + $current_nest = $current_tag; + continue; + } + } + + // Remove quotes from arguments for certain tags + if (strpos($current, '=') !== false && in_array($current_tag, $tags_quotes)) + { + $current = preg_replace('#\['.$current_tag.'=("|\'|)(.*?)\\1\]\s*#i', '['.$current_tag.'=$2]', $current); + } + + if (in_array($current_tag, array_keys($tags_limit_bbcode))) + $limit_bbcode = $tags_limit_bbcode[$current_tag]; + + $open_tags[] = $current_tag; + $open_args[] = $current_arg; + $opened_tag++; + $new_text .= $current; + continue; + } + } + + // Check we closed all the tags we needed to + foreach ($tags_closed as $check) + { + if (in_array($check, $open_tags)) + { + // We left an important tag open + $errors[] = sprintf($lang_common['BBCode error no closing tag'], $check); + return false; + } + } + + if ($current_ignore) + { + // We left an ignore tag open + $errors[] = sprintf($lang_common['BBCode error no closing tag'], $current_ignore); + return false; + } + + return $new_text; +} + + +// +// Preparse the contents of [list] bbcode +// +function preparse_list_tag($content, $type = '*', &$errors) +{ + global $lang_common, $re_list; + + if (strlen($type) != 1) + $type = '*'; + + if (strpos($content,'[list') !== false) + { + $content = preg_replace($re_list, 'preparse_list_tag(\'$2\', \'$1\', $errors)', $content); + } + + $items = explode('[*]', str_replace('\"', '"', $content)); + + $content = ''; + foreach ($items as $item) + { + if (pun_trim($item) != '') + $content .= '[*'."\0".']'.str_replace('[/*]', '', pun_trim($item)).'[/*'."\0".']'."\n"; + } + + return '[list='.$type.']'."\n".$content.'[/list]'; +} + + +// +// Split text into chunks ($inside contains all text inside $start and $end, and $outside contains all text outside) +// +function split_text($text, $start, $end, &$errors, $retab = true) +{ + global $pun_config, $lang_common; + + $tokens = explode($start, $text); + + $outside[] = $tokens[0]; + + $num_tokens = count($tokens); + for ($i = 1; $i < $num_tokens; ++$i) + { + $temp = explode($end, $tokens[$i]); + + if (count($temp) != 2) + { + $errors[] = $lang_common['BBCode code problem']; + return array(null, array($text)); + } + $inside[] = $temp[0]; + $outside[] = $temp[1]; + } + + if ($pun_config['o_indent_num_spaces'] != 8 && $retab) + { + $spaces = str_repeat(' ', $pun_config['o_indent_num_spaces']); + $inside = str_replace("\t", $spaces, $inside); + } + + return array($inside, $outside); +} + + +// +// Truncate URL if longer than 55 characters (add http:// or ftp:// if missing) +// +function handle_url_tag($url, $link = '', $bbcode = false) +{ + $url = pun_trim($url); + $full_url = str_replace(array(' ', '\'', '`', '"'), array('%20', '', '', ''), $url); + if (strpos($url, 'www.') === 0) // If it starts with www, we add http:// + $full_url = 'http://'.$full_url; + else if (strpos($url, 'ftp.') === 0) // Else if it starts with ftp, we add ftp:// + $full_url = 'ftp://'.$full_url; + else if (!preg_match('#^([a-z0-9]{3,6})://#', $url)) // Else if it doesn't start with abcdef://, we add http:// + $full_url = 'http://'.$full_url; + + // Ok, not very pretty :-) + if ($bbcode) + { + if ($full_url == $link) + return '[url]'.$link.'[/url]'; + else + return '[url='.$full_url.']'.$link.'[/url]'; + } + else + { + if ($link == '' || $link == $url) + { + $url = pun_htmlspecialchars_decode($url); + $link = utf8_strlen($url) > 55 ? utf8_substr($url, 0 , 39).' … '.utf8_substr($url, -10) : $url; + $link = pun_htmlspecialchars($link); + } + else + $link = stripslashes($link); + + return ''.$link.''; + } +} + + +// +// Turns an URL from the [img] tag into an tag or a tag +// +function handle_img_tag($url, $is_signature = false, $alt = null) +{ + global $lang_common, $pun_user; + + if ($alt == null) + $alt = basename($url); + + $img_tag = '<'.$lang_common['Image link'].' - '.$alt.'>'; + + if ($is_signature && $pun_user['show_img_sig'] != '0') + $img_tag = ''.$alt.''; + else if (!$is_signature && $pun_user['show_img'] != '0') + $img_tag = ''.$alt.''; + + return $img_tag; +} + + +// +// Parse the contents of [list] bbcode +// +function handle_list_tag($content, $type = '*') +{ + global $re_list; + + if (strlen($type) != 1) + $type = '*'; + + if (strpos($content,'[list') !== false) + { + $content = preg_replace($re_list, 'handle_list_tag(\'$2\', \'$1\')', $content); + } + + $content = preg_replace('#\s*\[\*\](.*?)\[/\*\]\s*#s', '
  • $1

  • ', pun_trim($content)); + + if ($type == '*') + $content = '
      '.$content.'
    '; + else + if ($type == 'a') + $content = '
      '.$content.'
    '; + else + $content = '
      '.$content.'
    '; + + return '

    '.$content.'

    '; +} + + +// +// Convert BBCodes to their HTML equivalent +// +function do_bbcode($text, $is_signature = false) +{ + global $lang_common, $pun_user, $pun_config, $re_list; + + if (strpos($text, '[quote') !== false) + { + $text = preg_replace('#\[quote\]\s*#', '

    ', $text); + $text = preg_replace('#\[quote=("|"|\'|)(.*?)\\1\]#se', '"

    ".str_replace(array(\'[\', \'\\"\'), array(\'[\', \'"\'), \'$2\')." ".$lang_common[\'wrote\']."

    "', $text); + $text = preg_replace('#\s*\[\/quote\]#S', '

    ', $text); + } + + if (!$is_signature) + { + $pattern[] = $re_list; + $replace[] = 'handle_list_tag(\'$2\', \'$1\')'; + } + + $pattern[] = '#\[b\](.*?)\[/b\]#ms'; + $pattern[] = '#\[i\](.*?)\[/i\]#ms'; + $pattern[] = '#\[u\](.*?)\[/u\]#ms'; + $pattern[] = '#\[s\](.*?)\[/s\]#ms'; + $pattern[] = '#\[del\](.*?)\[/del\]#ms'; + $pattern[] = '#\[ins\](.*?)\[/ins\]#ms'; + $pattern[] = '#\[em\](.*?)\[/em\]#ms'; + $pattern[] = '#\[colou?r=([a-zA-Z]{3,20}|\#[0-9a-fA-F]{6}|\#[0-9a-fA-F]{3})](.*?)\[/colou?r\]#ms'; + $pattern[] = '#\[h\](.*?)\[/h\]#ms'; + + $replace[] = '$1'; + $replace[] = '$1'; + $replace[] = '$1'; + $replace[] = '$1'; + $replace[] = '$1'; + $replace[] = '$1'; + $replace[] = '$1'; + $replace[] = '$2'; + $replace[] = '

    $1

    '; + + if (($is_signature && $pun_config['p_sig_img_tag'] == '1') || (!$is_signature && $pun_config['p_message_img_tag'] == '1')) + { + $pattern[] = '#\[img\]((ht|f)tps?://)([^\s<"]*?)\[/img\]#e'; + $pattern[] = '#\[img=([^\[]*?)\]((ht|f)tps?://)([^\s<"]*?)\[/img\]#e'; + if ($is_signature) + { + $replace[] = 'handle_img_tag(\'$1$3\', true)'; + $replace[] = 'handle_img_tag(\'$2$4\', true, \'$1\')'; + } + else + { + $replace[] = 'handle_img_tag(\'$1$3\', false)'; + $replace[] = 'handle_img_tag(\'$2$4\', false, \'$1\')'; + } + } + + $pattern[] = '#\[url\]([^\[]*?)\[/url\]#e'; + $pattern[] = '#\[url=([^\[]+?)\](.*?)\[/url\]#e'; + $pattern[] = '#\[email\]([^\[]*?)\[/email\]#'; + $pattern[] = '#\[email=([^\[]+?)\](.*?)\[/email\]#'; + + $replace[] = 'handle_url_tag(\'$1\')'; + $replace[] = 'handle_url_tag(\'$1\', \'$2\')'; + $replace[] = '$1'; + $replace[] = '$2'; + + // This thing takes a while! :) + $text = preg_replace($pattern, $replace, $text); + + return $text; +} + + +// +// Make hyperlinks clickable +// +function do_clickable($text) +{ + $text = ' '.$text; + + $text = preg_replace('#(?<=[\s\]\)])(<)?(\[)?(\()?([\'"]?)(https?|ftp|news){1}://([\w\-]+\.([\w\-]+\.)*\w+(:[0-9]+)?(/[^\s\[]*[^\s.,?!\[;:-])?)\4(?(3)(\)))(?(2)(\]))(?(1)(>))(?![^\s]*\[/(?:url|img)\])#ie', 'stripslashes(\'$1$2$3$4\').handle_url_tag(\'$5://$6\', \'$5://$6\', true).stripslashes(\'$4$10$11$12\')', $text); + $text = preg_replace('#(?<=[\s\]\)])(<)?(\[)?(\()?([\'"]?)(www|ftp)\.(([\w\-]+\.)*\w+(:[0-9]+)?(/[^\s\[]*[^\s.,?!\[;:-])?)\4(?(3)(\)))(?(2)(\]))(?(1)(>))(?![^\s]*\[/(?:url|img)\])#ie', 'stripslashes(\'$1$2$3$4\').handle_url_tag(\'$5.$6\', \'$5.$6\', true).stripslashes(\'$4$10$11$12\')', $text); + + return substr($text, 1); +} + + +// +// Convert a series of smilies to images +// +function do_smilies($text) +{ + global $pun_config, $smilies; + + $text = ' '.$text.' '; + + foreach ($smilies as $smiley_text => $smiley_img) + { + if (strpos($text, $smiley_text) !== false) + $text = preg_replace("#(?<=[>\s])".preg_quote($smiley_text, '#')."(?=\W)#m", ''.substr($smiley_img, 0, strrpos($smiley_img, '.')).'', $text); + } + + return substr($text, 1, -1); +} + + +// +// Parse message text +// +function parse_message($text, $hide_smilies) +{ + global $pun_config, $lang_common, $pun_user; + + if ($pun_config['o_censoring'] == '1') + $text = censor_words($text); + + // Convert applicable characters to HTML entities + $text = pun_htmlspecialchars($text); + + // If the message contains a code tag we have to split it up (text within [code][/code] shouldn't be touched) + if (strpos($text, '[code]') !== false && strpos($text, '[/code]') !== false) + { + list($inside, $outside) = split_text($text, '[code]', '[/code]', $errors); + $text = implode("\1", $outside); + } + + if ($pun_config['p_message_bbcode'] == '1' && strpos($text, '[') !== false && strpos($text, ']') !== false) + $text = do_bbcode($text); + + if ($pun_config['o_smilies'] == '1' && $pun_user['show_smilies'] == '1' && $hide_smilies == '0') + $text = do_smilies($text); + + // Deal with newlines, tabs and multiple spaces + $pattern = array("\n", "\t", ' ', ' '); + $replace = array('
    ', '    ', '  ', '  '); + $text = str_replace($pattern, $replace, $text); + + // If we split up the message before we have to concatenate it together again (code tags) + if (isset($inside)) + { + $outside = explode("\1", $text); + $text = ''; + + $num_tokens = count($outside); + + for ($i = 0; $i < $num_tokens; ++$i) + { + $text .= $outside[$i]; + if (isset($inside[$i])) + // $text .= '

    '.pun_trim($inside[$i], "\n\r").'

    '; + { + $num_lines = (substr_count($inside[$i], "\n")); + $text .= '

    28) ? ' class="vscroll"' : '').'>'.pun_trim($inside[$i], "\n\r").'

    '; + } + } + } + + // Add paragraph tag around post, but make sure there are no empty paragraphs + $text = preg_replace('#
    \s*?
    ((\s*
    )*)#i', "

    $1

    ", $text); + $text = str_replace('


    ', '

    ', $text); + $text = str_replace('

    ', '', '

    '.$text.'

    '); + + return $text; +} + + +// +// Parse signature text +// +function parse_signature($text) +{ + global $pun_config, $lang_common, $pun_user; + + if ($pun_config['o_censoring'] == '1') + $text = censor_words($text); + + // Convert applicable characters to HTML entities + $text = pun_htmlspecialchars($text); + + if ($pun_config['p_sig_bbcode'] == '1' && strpos($text, '[') !== false && strpos($text, ']') !== false) + $text = do_bbcode($text, true); + + if ($pun_config['o_smilies_sig'] == '1' && $pun_user['show_smilies'] == '1') + $text = do_smilies($text); + + + // Deal with newlines, tabs and multiple spaces + $pattern = array("\n", "\t", ' ', ' '); + $replace = array('
    ', '    ', '  ', '  '); + $text = str_replace($pattern, $replace, $text); + + // Add paragraph tag around post, but make sure there are no empty paragraphs + $text = preg_replace('#
    \s*?
    ((\s*
    )*)#i', "

    $1

    ", $text); + $text = str_replace('


    ', '

    ', $text); + $text = str_replace('

    ', '', '

    '.$text.'

    '); + + return $text; +} diff --git a/include/search_idx.php b/include/search_idx.php new file mode 100644 index 0000000..d43f5ea --- /dev/null +++ b/include/search_idx.php @@ -0,0 +1,311 @@ +`"„\|,@_\?~\+\[\]{}:=\/#\\\\;!\.…\s•'.($idx ? '%\*' : '').']+/u', ' ', $text); + + // Replace multiple dashes with just one + $text = preg_replace('/-{2,}/', '-', $text); + + // Fill an array with all the words + $words = array_unique(explode(' ', $text)); + + // Remove any words that should not be indexed + foreach ($words as $key => $value) + { + // If the word shouldn't be indexed, remove it + if (!validate_search_word($value, $idx)) + unset($words[$key]); + } + + return $words; +} + + +// +// Checks if a word is a valid searchable word +// +function validate_search_word($word, $idx) +{ + global $pun_user, $pun_config; + static $stopwords; + + // If the word is a keyword we don't want to index it, but we do want to be allowed to search it + if (is_keyword($word)) + return !$idx; + + $language = isset($pun_user['language']) ? $pun_user['language'] : $pun_config['o_default_lang']; + if (!isset($stopwords)) + { + if (file_exists(PUN_ROOT.'lang/'.$language.'/stopwords.txt')) + { + $stopwords = file(PUN_ROOT.'lang/'.$language.'/stopwords.txt'); + $stopwords = array_map('pun_trim', $stopwords); + $stopwords = array_filter($stopwords); + } + else + $stopwords = array(); + } + + // If it is a stopword it isn't valid + if (in_array($word, $stopwords)) + return false; + + // If the word if CJK we don't want to index it, but we do want to be allowed to search it + if (is_cjk($word)) + return !$idx; + + // Check the word is within the min/max length + $num_chars = pun_strlen($word); + return $num_chars >= PUN_SEARCH_MIN_WORD && $num_chars <= PUN_SEARCH_MAX_WORD; +} + + +// +// Check a given word is a search keyword. +// +function is_keyword($word) +{ + return $word == 'and' || $word == 'or' || $word == 'not'; +} + + +// +// Check if a given word is CJK or Hangul. +// +function is_cjk($word) +{ + return preg_match('/^'.PUN_CJK_HANGUL_REGEX.'+$/u', $word) ? true : false; +} + + +// +// Strip [img] [url] and [email] out of the message so we don't index their contents +// +function strip_bbcode($text) +{ + static $patterns; + + if (!isset($patterns)) + { + $patterns = array( + '%\[img=([^\]]*+)\][^[]*+\[/img\]%' => '$1', // Keep the alt description + '%\[(url|email)=[^\]]*+\]([^[]*+(?:(?!\[/\1\])\[[^[]*+)*)\[/\1\]%' => '$2', // Keep the text + '%\[(img|url|email)\]([^[]*+(?:(?!\[/\1\])\[[^[]*+)*)\[/\1\]%' => '', // Remove the whole thing + ); + } + + return preg_replace(array_keys($patterns), array_values($patterns), $text); +} + + +// +// Updates the search index with the contents of $post_id (and $subject) +// +function update_search_index($mode, $post_id, $message, $subject = null) +{ + global $db_type, $db; + + $message = utf8_strtolower($message); + $subject = utf8_strtolower($subject); + + // Remove any bbcode that we shouldn't index + $message = strip_bbcode($message); + + // Split old and new post/subject to obtain array of 'words' + $words_message = split_words($message, true); + $words_subject = ($subject) ? split_words($subject, true) : array(); + + if ($mode == 'edit') + { + $result = $db->query('SELECT w.id, w.word, m.subject_match FROM '.$db->prefix.'search_words AS w INNER JOIN '.$db->prefix.'search_matches AS m ON w.id=m.word_id WHERE m.post_id='.$post_id, true) or error('Unable to fetch search index words', __FILE__, __LINE__, $db->error()); + + // Declare here to stop array_keys() and array_diff() from complaining if not set + $cur_words['post'] = array(); + $cur_words['subject'] = array(); + + while ($row = $db->fetch_row($result)) + { + $match_in = ($row[2]) ? 'subject' : 'post'; + $cur_words[$match_in][$row[1]] = $row[0]; + } + + $db->free_result($result); + + $words['add']['post'] = array_diff($words_message, array_keys($cur_words['post'])); + $words['add']['subject'] = array_diff($words_subject, array_keys($cur_words['subject'])); + $words['del']['post'] = array_diff(array_keys($cur_words['post']), $words_message); + $words['del']['subject'] = array_diff(array_keys($cur_words['subject']), $words_subject); + } + else + { + $words['add']['post'] = $words_message; + $words['add']['subject'] = $words_subject; + $words['del']['post'] = array(); + $words['del']['subject'] = array(); + } + + unset($words_message); + unset($words_subject); + + // Get unique words from the above arrays + $unique_words = array_unique(array_merge($words['add']['post'], $words['add']['subject'])); + + if (!empty($unique_words)) + { + $result = $db->query('SELECT id, word FROM '.$db->prefix.'search_words WHERE word IN(\''.implode('\',\'', array_map(array($db, 'escape'), $unique_words)).'\')', true) or error('Unable to fetch search index words', __FILE__, __LINE__, $db->error()); + + $word_ids = array(); + while ($row = $db->fetch_row($result)) + $word_ids[$row[1]] = $row[0]; + + $db->free_result($result); + + $new_words = array_diff($unique_words, array_keys($word_ids)); + unset($unique_words); + + if (!empty($new_words)) + { + switch ($db_type) + { + case 'mysql': + case 'mysqli': + case 'mysql_innodb': + case 'mysqli_innodb': + $db->query('INSERT INTO '.$db->prefix.'search_words (word) VALUES(\''.implode('\'),(\'', array_map(array($db, 'escape'), $new_words)).'\')'); + break; + + default: + foreach ($new_words as $word) + $db->query('INSERT INTO '.$db->prefix.'search_words (word) VALUES(\''.$db->escape($word).'\')'); + break; + } + } + + unset($new_words); + } + + // Delete matches (only if editing a post) + foreach ($words['del'] as $match_in => $wordlist) + { + $subject_match = ($match_in == 'subject') ? 1 : 0; + + if (!empty($wordlist)) + { + $sql = ''; + foreach ($wordlist as $word) + $sql .= (($sql != '') ? ',' : '').$cur_words[$match_in][$word]; + + $db->query('DELETE FROM '.$db->prefix.'search_matches WHERE word_id IN('.$sql.') AND post_id='.$post_id.' AND subject_match='.$subject_match) or error('Unable to delete search index word matches', __FILE__, __LINE__, $db->error()); + } + } + + // Add new matches + foreach ($words['add'] as $match_in => $wordlist) + { + $subject_match = ($match_in == 'subject') ? 1 : 0; + + if (!empty($wordlist)) + $db->query('INSERT INTO '.$db->prefix.'search_matches (post_id, word_id, subject_match) SELECT '.$post_id.', id, '.$subject_match.' FROM '.$db->prefix.'search_words WHERE word IN(\''.implode('\',\'', array_map(array($db, 'escape'), $wordlist)).'\')') or error('Unable to insert search index word matches', __FILE__, __LINE__, $db->error()); + } + + unset($words); +} + + +// +// Strip search index of indexed words in $post_ids +// +function strip_search_index($post_ids) +{ + global $db_type, $db; + + switch ($db_type) + { + case 'mysql': + case 'mysqli': + case 'mysql_innodb': + case 'mysqli_innodb': + { + $result = $db->query('SELECT word_id FROM '.$db->prefix.'search_matches WHERE post_id IN('.$post_ids.') GROUP BY word_id') or error('Unable to fetch search index word match', __FILE__, __LINE__, $db->error()); + + if ($db->num_rows($result)) + { + $word_ids = ''; + while ($row = $db->fetch_row($result)) + $word_ids .= ($word_ids != '') ? ','.$row[0] : $row[0]; + + $result = $db->query('SELECT word_id FROM '.$db->prefix.'search_matches WHERE word_id IN('.$word_ids.') GROUP BY word_id HAVING COUNT(word_id)=1') or error('Unable to fetch search index word match', __FILE__, __LINE__, $db->error()); + + if ($db->num_rows($result)) + { + $word_ids = ''; + while ($row = $db->fetch_row($result)) + $word_ids .= ($word_ids != '') ? ','.$row[0] : $row[0]; + + $db->query('DELETE FROM '.$db->prefix.'search_words WHERE id IN('.$word_ids.')') or error('Unable to delete search index word', __FILE__, __LINE__, $db->error()); + } + } + + break; + } + + default: + $db->query('DELETE FROM '.$db->prefix.'search_words WHERE id IN(SELECT word_id FROM '.$db->prefix.'search_matches WHERE word_id IN(SELECT word_id FROM '.$db->prefix.'search_matches WHERE post_id IN('.$post_ids.') GROUP BY word_id) GROUP BY word_id HAVING COUNT(word_id)=1)') or error('Unable to delete from search index', __FILE__, __LINE__, $db->error()); + break; + } + + $db->query('DELETE FROM '.$db->prefix.'search_matches WHERE post_id IN('.$post_ids.')') or error('Unable to delete search index word match', __FILE__, __LINE__, $db->error()); +} diff --git a/include/template/admin.tpl b/include/template/admin.tpl new file mode 100644 index 0000000..06679ee --- /dev/null +++ b/include/template/admin.tpl @@ -0,0 +1,38 @@ + + + + + + + + + +
    +
    +
    + +
    +
    +
    + + +
    + + +
    +
    + + + +
    + +
    + + + +
    +
    +
    + + + diff --git a/include/template/help.tpl b/include/template/help.tpl new file mode 100644 index 0000000..58fec14 --- /dev/null +++ b/include/template/help.tpl @@ -0,0 +1,23 @@ + + + + + + + + + +
    +
    +
    + +
    + +
    + +
    +
    +
    + + + diff --git a/include/template/index.html b/include/template/index.html new file mode 100644 index 0000000..89337b2 --- /dev/null +++ b/include/template/index.html @@ -0,0 +1 @@ +.. diff --git a/include/template/main.tpl b/include/template/main.tpl new file mode 100644 index 0000000..ea0a0b6 --- /dev/null +++ b/include/template/main.tpl @@ -0,0 +1,38 @@ + + + + + + + + + +
    +
    +
    + +
    +
    +
    + + +
    + + +
    +
    + + + +
    + +
    + + + +
    +
    +
    + + + diff --git a/include/template/maintenance.tpl b/include/template/maintenance.tpl new file mode 100644 index 0000000..56edc49 --- /dev/null +++ b/include/template/maintenance.tpl @@ -0,0 +1,23 @@ + + + + + + + + + +
    +
    +
    + +
    + +
    + +
    +
    +
    + + + diff --git a/include/template/redirect.tpl b/include/template/redirect.tpl new file mode 100644 index 0000000..31f5f19 --- /dev/null +++ b/include/template/redirect.tpl @@ -0,0 +1,25 @@ + + + + + + + + + +
    +
    +
    + +
    + +
    + + + +
    +
    +
    + + + diff --git a/include/utf8/index.html b/include/utf8/index.html new file mode 100644 index 0000000..89337b2 --- /dev/null +++ b/include/utf8/index.html @@ -0,0 +1 @@ +.. diff --git a/include/utf8/mbstring/core.php b/include/utf8/mbstring/core.php new file mode 100644 index 0000000..bea1c32 --- /dev/null +++ b/include/utf8/mbstring/core.php @@ -0,0 +1,144 @@ +.. diff --git a/include/utf8/native/core.php b/include/utf8/native/core.php new file mode 100644 index 0000000..58636f5 --- /dev/null +++ b/include/utf8/native/core.php @@ -0,0 +1,422 @@ + +* @link http://www.php.net/manual/en/function.strlen.php +* @link http://www.php.net/manual/en/function.utf8-decode.php +* @param string UTF-8 string +* @return int number of UTF-8 characters in string +* @package utf8 +* @subpackage strings +*/ +function utf8_strlen($str) +{ + return strlen(utf8_decode($str)); +} + +/** +* UTF-8 aware alternative to strpos +* Find position of first occurrence of a string +* Note: This will get alot slower if offset is used +* Note: requires utf8_strlen amd utf8_substr to be loaded +* @param string haystack +* @param string needle (you should validate this with utf8_is_valid) +* @param integer offset in characters (from left) +* @return mixed integer position or FALSE on failure +* @see http://www.php.net/strpos +* @see utf8_strlen +* @see utf8_substr +* @package utf8 +* @subpackage strings +*/ +function utf8_strpos($str, $needle, $offset = false) +{ + if ($offset === false) + { + $ar = explode($needle, $str, 2); + + if (count($ar) > 1) + return utf8_strlen($ar[0]); + + return false; + } + else + { + if (!is_int($offset)) + { + trigger_error('utf8_strpos: Offset must be an integer', E_USER_ERROR); + return false; + } + + $str = utf8_substr($str, $offset); + + if (($pos = utf8_strpos($str, $needle)) !== false) + return $pos + $offset; + + return false; + } +} + +/** +* UTF-8 aware alternative to strrpos +* Find position of last occurrence of a char in a string +* Note: This will get alot slower if offset is used +* Note: requires utf8_substr and utf8_strlen to be loaded +* @param string haystack +* @param string needle (you should validate this with utf8_is_valid) +* @param integer (optional) offset (from left) +* @return mixed integer position or FALSE on failure +* @see http://www.php.net/strrpos +* @see utf8_substr +* @see utf8_strlen +* @package utf8 +* @subpackage strings +*/ +function utf8_strrpos($str, $needle, $offset = false) +{ + if ($offset === false) + { + $ar = explode($needle, $str); + + if (count($ar) > 1) + { + // Pop off the end of the string where the last match was made + array_pop($ar); + $str = join($needle, $ar); + + return utf8_strlen($str); + } + + return false; + } + else + { + if (!is_int($offset)) + { + trigger_error('utf8_strrpos expects parameter 3 to be long', E_USER_WARNING); + return false; + } + + $str = utf8_substr($str, $offset); + + if (($pos = utf8_strrpos($str, $needle)) !== false) + return $pos + $offset; + + return false; + } +} + +/** +* UTF-8 aware alternative to substr +* Return part of a string given character offset (and optionally length) +* +* Note arguments: comparied to substr - if offset or length are +* not integers, this version will not complain but rather massages them +* into an integer. +* +* Note on returned values: substr documentation states false can be +* returned in some cases (e.g. offset > string length) +* mb_substr never returns false, it will return an empty string instead. +* This adopts the mb_substr approach +* +* Note on implementation: PCRE only supports repetitions of less than +* 65536, in order to accept up to MAXINT values for offset and length, +* we'll repeat a group of 65535 characters when needed. +* +* Note on implementation: calculating the number of characters in the +* string is a relatively expensive operation, so we only carry it out when +* necessary. It isn't necessary for +ve offsets and no specified length +* +* @author Chris Smith +* @param string +* @param integer number of UTF-8 characters offset (from left) +* @param integer (optional) length in UTF-8 characters from offset +* @return mixed string or FALSE if failure +* @package utf8 +* @subpackage strings +*/ +function utf8_substr($str, $offset, $length = false) +{ + // Generates E_NOTICE for PHP4 objects, but not PHP5 objects + $str = (string) $str; + $offset = (int) $offset; + + if ($length) + $length = (int) $length; + + // Handle trivial cases + if ($length === 0) + return ''; + if ($offset < 0 && $length < 0 && $length < $offset) + return ''; + + // Normalise negative offsets (we could use a tail + // anchored pattern, but they are horribly slow!) + if ($offset < 0) + { + // See notes + $strlen = utf8_strlen($str); + $offset = $strlen + $offset; + + if ($offset < 0) + $offset = 0; + } + + $Op = ''; + $Lp = ''; + + // Establish a pattern for offset, a + // non-captured group equal in length to offset + if ($offset > 0) + { + $Ox = (int) ($offset / 65535); + $Oy = $offset % 65535; + + if ($Ox) + $Op = '(?:.{65535}){'.$Ox.'}'; + + $Op = '^(?:'.$Op.'.{'.$Oy.'})'; + } + else + $Op = '^'; + + + // Establish a pattern for length + if (!$length) + { + // The rest of the string + $Lp = '(.*)$'; + } + else + { + // See notes + if (!isset($strlen)) + $strlen = strlen(utf8_decode($str)); + + // Another trivial case + if ($offset > $strlen) + return ''; + + if ($length > 0) + { + // Reduce any length that would go passed the end of the string + $length = min($strlen-$offset, $length); + + $Lx = (int)( $length / 65535 ); + $Ly = $length % 65535; + + // Negative length requires a captured group of length characters + if ($Lx) $Lp = '(?:.{65535}){'.$Lx.'}'; + $Lp = '('.$Lp.'.{'.$Ly.'})'; + } + else if ($length < 0) + { + + if ($length < ($offset - $strlen)) + return ''; + + $Lx = (int)((-$length)/65535); + $Ly = (-$length)%65535; + + // Negative length requires ... capture everything except a group of + // -length characters anchored at the tail-end of the string + if ($Lx) + $Lp = '(?:.{65535}){'.$Lx.'}'; + + $Lp = '(.*)(?:'.$Lp.'.{'.$Ly.'})$'; + } + } + + if (!preg_match('#'.$Op.$Lp.'#us', $str, $match)) + return ''; + + return $match[1]; +} + +/** +* UTF-8 aware alternative to strtolower +* Make a string lowercase +* Note: The concept of a characters "case" only exists is some alphabets +* such as Latin, Greek, Cyrillic, Armenian and archaic Georgian - it does +* not exist in the Chinese alphabet, for example. See Unicode Standard +* Annex #21: Case Mappings +* Note: requires utf8_to_unicode and utf8_from_unicode +* @author Andreas Gohr +* @param string +* @return mixed either string in lowercase or FALSE is UTF-8 invalid +* @see http://www.php.net/strtolower +* @see utf8_to_unicode +* @see utf8_from_unicode +* @see http://www.unicode.org/reports/tr21/tr21-5.html +* @see http://dev.splitbrain.org/view/darcs/dokuwiki/inc/utf8.php +* @package utf8 +* @subpackage strings +*/ +function utf8_strtolower($string) +{ + static $UTF8_UPPER_TO_LOWER = false; + + if (!$UTF8_UPPER_TO_LOWER) + { + $UTF8_UPPER_TO_LOWER = array( + 0x0041=>0x0061, 0x03A6=>0x03C6, 0x0162=>0x0163, 0x00C5=>0x00E5, 0x0042=>0x0062, + 0x0139=>0x013A, 0x00C1=>0x00E1, 0x0141=>0x0142, 0x038E=>0x03CD, 0x0100=>0x0101, + 0x0490=>0x0491, 0x0394=>0x03B4, 0x015A=>0x015B, 0x0044=>0x0064, 0x0393=>0x03B3, + 0x00D4=>0x00F4, 0x042A=>0x044A, 0x0419=>0x0439, 0x0112=>0x0113, 0x041C=>0x043C, + 0x015E=>0x015F, 0x0143=>0x0144, 0x00CE=>0x00EE, 0x040E=>0x045E, 0x042F=>0x044F, + 0x039A=>0x03BA, 0x0154=>0x0155, 0x0049=>0x0069, 0x0053=>0x0073, 0x1E1E=>0x1E1F, + 0x0134=>0x0135, 0x0427=>0x0447, 0x03A0=>0x03C0, 0x0418=>0x0438, 0x00D3=>0x00F3, + 0x0420=>0x0440, 0x0404=>0x0454, 0x0415=>0x0435, 0x0429=>0x0449, 0x014A=>0x014B, + 0x0411=>0x0431, 0x0409=>0x0459, 0x1E02=>0x1E03, 0x00D6=>0x00F6, 0x00D9=>0x00F9, + 0x004E=>0x006E, 0x0401=>0x0451, 0x03A4=>0x03C4, 0x0423=>0x0443, 0x015C=>0x015D, + 0x0403=>0x0453, 0x03A8=>0x03C8, 0x0158=>0x0159, 0x0047=>0x0067, 0x00C4=>0x00E4, + 0x0386=>0x03AC, 0x0389=>0x03AE, 0x0166=>0x0167, 0x039E=>0x03BE, 0x0164=>0x0165, + 0x0116=>0x0117, 0x0108=>0x0109, 0x0056=>0x0076, 0x00DE=>0x00FE, 0x0156=>0x0157, + 0x00DA=>0x00FA, 0x1E60=>0x1E61, 0x1E82=>0x1E83, 0x00C2=>0x00E2, 0x0118=>0x0119, + 0x0145=>0x0146, 0x0050=>0x0070, 0x0150=>0x0151, 0x042E=>0x044E, 0x0128=>0x0129, + 0x03A7=>0x03C7, 0x013D=>0x013E, 0x0422=>0x0442, 0x005A=>0x007A, 0x0428=>0x0448, + 0x03A1=>0x03C1, 0x1E80=>0x1E81, 0x016C=>0x016D, 0x00D5=>0x00F5, 0x0055=>0x0075, + 0x0176=>0x0177, 0x00DC=>0x00FC, 0x1E56=>0x1E57, 0x03A3=>0x03C3, 0x041A=>0x043A, + 0x004D=>0x006D, 0x016A=>0x016B, 0x0170=>0x0171, 0x0424=>0x0444, 0x00CC=>0x00EC, + 0x0168=>0x0169, 0x039F=>0x03BF, 0x004B=>0x006B, 0x00D2=>0x00F2, 0x00C0=>0x00E0, + 0x0414=>0x0434, 0x03A9=>0x03C9, 0x1E6A=>0x1E6B, 0x00C3=>0x00E3, 0x042D=>0x044D, + 0x0416=>0x0436, 0x01A0=>0x01A1, 0x010C=>0x010D, 0x011C=>0x011D, 0x00D0=>0x00F0, + 0x013B=>0x013C, 0x040F=>0x045F, 0x040A=>0x045A, 0x00C8=>0x00E8, 0x03A5=>0x03C5, + 0x0046=>0x0066, 0x00DD=>0x00FD, 0x0043=>0x0063, 0x021A=>0x021B, 0x00CA=>0x00EA, + 0x0399=>0x03B9, 0x0179=>0x017A, 0x00CF=>0x00EF, 0x01AF=>0x01B0, 0x0045=>0x0065, + 0x039B=>0x03BB, 0x0398=>0x03B8, 0x039C=>0x03BC, 0x040C=>0x045C, 0x041F=>0x043F, + 0x042C=>0x044C, 0x00DE=>0x00FE, 0x00D0=>0x00F0, 0x1EF2=>0x1EF3, 0x0048=>0x0068, + 0x00CB=>0x00EB, 0x0110=>0x0111, 0x0413=>0x0433, 0x012E=>0x012F, 0x00C6=>0x00E6, + 0x0058=>0x0078, 0x0160=>0x0161, 0x016E=>0x016F, 0x0391=>0x03B1, 0x0407=>0x0457, + 0x0172=>0x0173, 0x0178=>0x00FF, 0x004F=>0x006F, 0x041B=>0x043B, 0x0395=>0x03B5, + 0x0425=>0x0445, 0x0120=>0x0121, 0x017D=>0x017E, 0x017B=>0x017C, 0x0396=>0x03B6, + 0x0392=>0x03B2, 0x0388=>0x03AD, 0x1E84=>0x1E85, 0x0174=>0x0175, 0x0051=>0x0071, + 0x0417=>0x0437, 0x1E0A=>0x1E0B, 0x0147=>0x0148, 0x0104=>0x0105, 0x0408=>0x0458, + 0x014C=>0x014D, 0x00CD=>0x00ED, 0x0059=>0x0079, 0x010A=>0x010B, 0x038F=>0x03CE, + 0x0052=>0x0072, 0x0410=>0x0430, 0x0405=>0x0455, 0x0402=>0x0452, 0x0126=>0x0127, + 0x0136=>0x0137, 0x012A=>0x012B, 0x038A=>0x03AF, 0x042B=>0x044B, 0x004C=>0x006C, + 0x0397=>0x03B7, 0x0124=>0x0125, 0x0218=>0x0219, 0x00DB=>0x00FB, 0x011E=>0x011F, + 0x041E=>0x043E, 0x1E40=>0x1E41, 0x039D=>0x03BD, 0x0106=>0x0107, 0x03AB=>0x03CB, + 0x0426=>0x0446, 0x00DE=>0x00FE, 0x00C7=>0x00E7, 0x03AA=>0x03CA, 0x0421=>0x0441, + 0x0412=>0x0432, 0x010E=>0x010F, 0x00D8=>0x00F8, 0x0057=>0x0077, 0x011A=>0x011B, + 0x0054=>0x0074, 0x004A=>0x006A, 0x040B=>0x045B, 0x0406=>0x0456, 0x0102=>0x0103, + 0x039B=>0x03BB, 0x00D1=>0x00F1, 0x041D=>0x043D, 0x038C=>0x03CC, 0x00C9=>0x00E9, + 0x00D0=>0x00F0, 0x0407=>0x0457, 0x0122=>0x0123); + } + + $uni = utf8_to_unicode($string); + + if (!$uni) + return false; + + $cnt = count($uni); + + for ($i=0; $i < $cnt; $i++) + if (isset($UTF8_UPPER_TO_LOWER[$uni[$i]])) + $uni[$i] = $UTF8_UPPER_TO_LOWER[$uni[$i]]; + + return utf8_from_unicode($uni); +} + +/** +* UTF-8 aware alternative to strtoupper +* Make a string uppercase +* Note: The concept of a characters "case" only exists is some alphabets +* such as Latin, Greek, Cyrillic, Armenian and archaic Georgian - it does +* not exist in the Chinese alphabet, for example. See Unicode Standard +* Annex #21: Case Mappings +* Note: requires utf8_to_unicode and utf8_from_unicode +* @author Andreas Gohr +* @param string +* @return mixed either string in lowercase or FALSE is UTF-8 invalid +* @see http://www.php.net/strtoupper +* @see utf8_to_unicode +* @see utf8_from_unicode +* @see http://www.unicode.org/reports/tr21/tr21-5.html +* @see http://dev.splitbrain.org/view/darcs/dokuwiki/inc/utf8.php +* @package utf8 +* @subpackage strings +*/ +function utf8_strtoupper($string) +{ + static $UTF8_LOWER_TO_UPPER = false; + + if (!$UTF8_LOWER_TO_UPPER) + { + $UTF8_LOWER_TO_UPPER = array( + 0x0061=>0x0041, 0x03C6=>0x03A6, 0x0163=>0x0162, 0x00E5=>0x00C5, 0x0062=>0x0042, + 0x013A=>0x0139, 0x00E1=>0x00C1, 0x0142=>0x0141, 0x03CD=>0x038E, 0x0101=>0x0100, + 0x0491=>0x0490, 0x03B4=>0x0394, 0x015B=>0x015A, 0x0064=>0x0044, 0x03B3=>0x0393, + 0x00F4=>0x00D4, 0x044A=>0x042A, 0x0439=>0x0419, 0x0113=>0x0112, 0x043C=>0x041C, + 0x015F=>0x015E, 0x0144=>0x0143, 0x00EE=>0x00CE, 0x045E=>0x040E, 0x044F=>0x042F, + 0x03BA=>0x039A, 0x0155=>0x0154, 0x0069=>0x0049, 0x0073=>0x0053, 0x1E1F=>0x1E1E, + 0x0135=>0x0134, 0x0447=>0x0427, 0x03C0=>0x03A0, 0x0438=>0x0418, 0x00F3=>0x00D3, + 0x0440=>0x0420, 0x0454=>0x0404, 0x0435=>0x0415, 0x0449=>0x0429, 0x014B=>0x014A, + 0x0431=>0x0411, 0x0459=>0x0409, 0x1E03=>0x1E02, 0x00F6=>0x00D6, 0x00F9=>0x00D9, + 0x006E=>0x004E, 0x0451=>0x0401, 0x03C4=>0x03A4, 0x0443=>0x0423, 0x015D=>0x015C, + 0x0453=>0x0403, 0x03C8=>0x03A8, 0x0159=>0x0158, 0x0067=>0x0047, 0x00E4=>0x00C4, + 0x03AC=>0x0386, 0x03AE=>0x0389, 0x0167=>0x0166, 0x03BE=>0x039E, 0x0165=>0x0164, + 0x0117=>0x0116, 0x0109=>0x0108, 0x0076=>0x0056, 0x00FE=>0x00DE, 0x0157=>0x0156, + 0x00FA=>0x00DA, 0x1E61=>0x1E60, 0x1E83=>0x1E82, 0x00E2=>0x00C2, 0x0119=>0x0118, + 0x0146=>0x0145, 0x0070=>0x0050, 0x0151=>0x0150, 0x044E=>0x042E, 0x0129=>0x0128, + 0x03C7=>0x03A7, 0x013E=>0x013D, 0x0442=>0x0422, 0x007A=>0x005A, 0x0448=>0x0428, + 0x03C1=>0x03A1, 0x1E81=>0x1E80, 0x016D=>0x016C, 0x00F5=>0x00D5, 0x0075=>0x0055, + 0x0177=>0x0176, 0x00FC=>0x00DC, 0x1E57=>0x1E56, 0x03C3=>0x03A3, 0x043A=>0x041A, + 0x006D=>0x004D, 0x016B=>0x016A, 0x0171=>0x0170, 0x0444=>0x0424, 0x00EC=>0x00CC, + 0x0169=>0x0168, 0x03BF=>0x039F, 0x006B=>0x004B, 0x00F2=>0x00D2, 0x00E0=>0x00C0, + 0x0434=>0x0414, 0x03C9=>0x03A9, 0x1E6B=>0x1E6A, 0x00E3=>0x00C3, 0x044D=>0x042D, + 0x0436=>0x0416, 0x01A1=>0x01A0, 0x010D=>0x010C, 0x011D=>0x011C, 0x00F0=>0x00D0, + 0x013C=>0x013B, 0x045F=>0x040F, 0x045A=>0x040A, 0x00E8=>0x00C8, 0x03C5=>0x03A5, + 0x0066=>0x0046, 0x00FD=>0x00DD, 0x0063=>0x0043, 0x021B=>0x021A, 0x00EA=>0x00CA, + 0x03B9=>0x0399, 0x017A=>0x0179, 0x00EF=>0x00CF, 0x01B0=>0x01AF, 0x0065=>0x0045, + 0x03BB=>0x039B, 0x03B8=>0x0398, 0x03BC=>0x039C, 0x045C=>0x040C, 0x043F=>0x041F, + 0x044C=>0x042C, 0x00FE=>0x00DE, 0x00F0=>0x00D0, 0x1EF3=>0x1EF2, 0x0068=>0x0048, + 0x00EB=>0x00CB, 0x0111=>0x0110, 0x0433=>0x0413, 0x012F=>0x012E, 0x00E6=>0x00C6, + 0x0078=>0x0058, 0x0161=>0x0160, 0x016F=>0x016E, 0x03B1=>0x0391, 0x0457=>0x0407, + 0x0173=>0x0172, 0x00FF=>0x0178, 0x006F=>0x004F, 0x043B=>0x041B, 0x03B5=>0x0395, + 0x0445=>0x0425, 0x0121=>0x0120, 0x017E=>0x017D, 0x017C=>0x017B, 0x03B6=>0x0396, + 0x03B2=>0x0392, 0x03AD=>0x0388, 0x1E85=>0x1E84, 0x0175=>0x0174, 0x0071=>0x0051, + 0x0437=>0x0417, 0x1E0B=>0x1E0A, 0x0148=>0x0147, 0x0105=>0x0104, 0x0458=>0x0408, + 0x014D=>0x014C, 0x00ED=>0x00CD, 0x0079=>0x0059, 0x010B=>0x010A, 0x03CE=>0x038F, + 0x0072=>0x0052, 0x0430=>0x0410, 0x0455=>0x0405, 0x0452=>0x0402, 0x0127=>0x0126, + 0x0137=>0x0136, 0x012B=>0x012A, 0x03AF=>0x038A, 0x044B=>0x042B, 0x006C=>0x004C, + 0x03B7=>0x0397, 0x0125=>0x0124, 0x0219=>0x0218, 0x00FB=>0x00DB, 0x011F=>0x011E, + 0x043E=>0x041E, 0x1E41=>0x1E40, 0x03BD=>0x039D, 0x0107=>0x0106, 0x03CB=>0x03AB, + 0x0446=>0x0426, 0x00FE=>0x00DE, 0x00E7=>0x00C7, 0x03CA=>0x03AA, 0x0441=>0x0421, + 0x0432=>0x0412, 0x010F=>0x010E, 0x00F8=>0x00D8, 0x0077=>0x0057, 0x011B=>0x011A, + 0x0074=>0x0054, 0x006A=>0x004A, 0x045B=>0x040B, 0x0456=>0x0406, 0x0103=>0x0102, + 0x03BB=>0x039B, 0x00F1=>0x00D1, 0x043D=>0x041D, 0x03CC=>0x038C, 0x00E9=>0x00C9, + 0x00F0=>0x00D0, 0x0457=>0x0407, 0x0123=>0x0122); + } + + $uni = utf8_to_unicode($string); + + if (!$uni) + return false; + + $cnt = count($uni); + + for ($i=0; $i < $cnt; $i++) + if(isset($UTF8_LOWER_TO_UPPER[$uni[$i]])) + $uni[$i] = $UTF8_LOWER_TO_UPPER[$uni[$i]]; + + return utf8_from_unicode($uni); +} diff --git a/include/utf8/native/index.html b/include/utf8/native/index.html new file mode 100644 index 0000000..89337b2 --- /dev/null +++ b/include/utf8/native/index.html @@ -0,0 +1 @@ +.. diff --git a/include/utf8/ord.php b/include/utf8/ord.php new file mode 100644 index 0000000..a333f96 --- /dev/null +++ b/include/utf8/ord.php @@ -0,0 +1,78 @@ += 0 && $ord0 <= 127) + return $ord0; + + if (!isset($chr{1})) + { + trigger_error('Short sequence - at least 2 bytes expected, only 1 seen'); + return false; + } + + $ord1 = ord($chr{1}); + if ($ord0 >= 192 && $ord0 <= 223) + return ($ord0 - 192) * 64 + ($ord1 - 128); + + if (!isset($chr{2})) + { + trigger_error('Short sequence - at least 3 bytes expected, only 2 seen'); + return false; + } + + $ord2 = ord($chr{2}); + if ($ord0 >= 224 && $ord0 <= 239) + return ($ord0-224)*4096 + ($ord1-128)*64 + ($ord2-128); + + if (!isset($chr{3})) + { + trigger_error('Short sequence - at least 4 bytes expected, only 3 seen'); + return false; + } + + $ord3 = ord($chr{3}); + if ($ord0>=240 && $ord0<=247) + return ($ord0-240)*262144 + ($ord1-128)*4096 + ($ord2-128)*64 + ($ord3-128); + + if (!isset($chr{4})) + { + trigger_error('Short sequence - at least 5 bytes expected, only 4 seen'); + return false; + } + + $ord4 = ord($chr{4}); + if ($ord0>=248 && $ord0<=251) + return ($ord0-248)*16777216 + ($ord1-128)*262144 + ($ord2-128)*4096 + ($ord3-128)*64 + ($ord4-128); + + if (!isset($chr{5})) + { + trigger_error('Short sequence - at least 6 bytes expected, only 5 seen'); + return false; + } + + if ($ord0>=252 && $ord0<=253) + return ($ord0-252) * 1073741824 + ($ord1-128)*16777216 + ($ord2-128)*262144 + ($ord3-128)*4096 + ($ord4-128)*64 + (ord($c{5})-128); + + if ($ord0 >= 254 && $ord0 <= 255) + { + trigger_error('Invalid UTF-8 with surrogate ordinal '.$ord0); + return false; + } +} diff --git a/include/utf8/str_ireplace.php b/include/utf8/str_ireplace.php new file mode 100644 index 0000000..7257b0a --- /dev/null +++ b/include/utf8/str_ireplace.php @@ -0,0 +1,72 @@ + +* @param string $input +* @param int $length +* @param string $padStr +* @param int $type ( same constants as str_pad ) +* @return string +* @see http://www.php.net/str_pad +* @see utf8_substr +* @package utf8 +* @subpackage strings +*/ +function utf8_str_pad($input, $length, $padStr=' ', $type=STR_PAD_RIGHT) +{ + $inputLen = utf8_strlen($input); + if ($length <= $inputLen) + return $input; + + $padStrLen = utf8_strlen($padStr); + $padLen = $length - $inputLen; + + if ($type == STR_PAD_RIGHT) + { + $repeatTimes = ceil($padLen / $padStrLen); + return utf8_substr($input.str_repeat($padStr, $repeatTimes), 0, $length); + } + + if ($type == STR_PAD_LEFT) + { + $repeatTimes = ceil($padLen / $padStrLen); + return utf8_substr(str_repeat($padStr, $repeatTimes), 0, floor($padLen)).$input; + } + + if ($type == STR_PAD_BOTH) + { + $padLen /= 2; + $padAmountLeft = floor($padLen); + $padAmountRight = ceil($padLen); + $repeatTimesLeft = ceil($padAmountLeft / $padStrLen); + $repeatTimesRight = ceil($padAmountRight / $padStrLen); + + $paddingLeft = utf8_substr(str_repeat($padStr, $repeatTimesLeft), 0, $padAmountLeft); + $paddingRight = utf8_substr(str_repeat($padStr, $repeatTimesRight), 0, $padAmountLeft); + + return $paddingLeft.$input.$paddingRight; + } + + trigger_error('utf8_str_pad: Unknown padding type ('.$type.')', E_USER_ERROR); +} diff --git a/include/utf8/str_split.php b/include/utf8/str_split.php new file mode 100644 index 0000000..15bc215 --- /dev/null +++ b/include/utf8/str_split.php @@ -0,0 +1,33 @@ + +* @see http://www.php.net/ltrim +* @see http://dev.splitbrain.org/view/darcs/dokuwiki/inc/utf8.php +* @return string +* @package utf8 +* @subpackage strings +*/ +function utf8_ltrim( $str, $charlist=false) +{ + if($charlist === false) + return ltrim($str); + + // Quote charlist for use in a characterclass + $charlist = preg_replace('!([\\\\\\-\\]\\[/^])!', '\\\${1}', $charlist); + + return preg_replace('/^['.$charlist.']+/u', '', $str); +} + +/** +* UTF-8 aware replacement for rtrim() +* Note: you only need to use this if you are supplying the charlist +* optional arg and it contains UTF-8 characters. Otherwise rtrim will +* work normally on a UTF-8 string +* @author Andreas Gohr +* @see http://www.php.net/rtrim +* @see http://dev.splitbrain.org/view/darcs/dokuwiki/inc/utf8.php +* @return string +* @package utf8 +* @subpackage strings +*/ +function utf8_rtrim($str, $charlist=false) +{ + if($charlist === false) + return rtrim($str); + + // Quote charlist for use in a characterclass + $charlist = preg_replace('!([\\\\\\-\\]\\[/^])!', '\\\${1}', $charlist); + + return preg_replace('/['.$charlist.']+$/u', '', $str); +} + +//--------------------------------------------------------------- +/** +* UTF-8 aware replacement for trim() +* Note: you only need to use this if you are supplying the charlist +* optional arg and it contains UTF-8 characters. Otherwise trim will +* work normally on a UTF-8 string +* @author Andreas Gohr +* @see http://www.php.net/trim +* @see http://dev.splitbrain.org/view/darcs/dokuwiki/inc/utf8.php +* @return string +* @package utf8 +* @subpackage strings +*/ +function utf8_trim( $str, $charlist=false) +{ + if($charlist === false) + return trim($str); + + return utf8_ltrim(utf8_rtrim($str, $charlist), $charlist); +} diff --git a/include/utf8/ucfirst.php b/include/utf8/ucfirst.php new file mode 100644 index 0000000..efee55d --- /dev/null +++ b/include/utf8/ucfirst.php @@ -0,0 +1,35 @@ + +* if ( utf8_is_ascii($someString) ) { +* // It's just ASCII - use the native PHP version +* $someString = strtolower($someString); +* } else { +* $someString = utf8_strtolower($someString); +* } +* +* +* @param string +* @return boolean TRUE if it's all ASCII +* @package utf8 +* @subpackage ascii +* @see utf8_is_ascii_ctrl +*/ +function utf8_is_ascii($str) +{ + // Search for any bytes which are outside the ASCII range... + return (preg_match('/(?:[^\x00-\x7F])/', $str) !== 1); +} + +/** +* Tests whether a string contains only 7bit ASCII bytes with device +* control codes omitted. The device control codes can be found on the +* second table here: http://www.w3schools.com/tags/ref_ascii.asp +* +* @param string +* @return boolean TRUE if it's all ASCII without device control codes +* @package utf8 +* @subpackage ascii +* @see utf8_is_ascii +*/ +function utf8_is_ascii_ctrl($str) +{ + // Search for any bytes which are outside the ASCII range, or are device control codes + if (strlen($str) > 0) + return (preg_match('/[^\x09\x0A\x0D\x20-\x7E]/', $str) !== 1); + + return false; +} + +/** +* Strip out all non-7bit ASCII bytes +* If you need to transmit a string to system which you know can only +* support 7bit ASCII, you could use this function. +* @param string +* @return string with non ASCII bytes removed +* @package utf8 +* @subpackage ascii +* @see utf8_strip_non_ascii_ctrl +*/ +function utf8_strip_non_ascii($str) +{ + ob_start(); + + while (preg_match('/^([\x00-\x7F]+)|([^\x00-\x7F]+)/S', $str, $matches)) + { + if (!isset($matches[2])) + echo $matches[0]; + + $str = substr($str, strlen($matches[0])); + } + + $result = ob_get_contents(); + ob_end_clean(); + + return $result; +} + +/** +* Strip out device control codes in the ASCII range +* which are not permitted in XML. Note that this leaves +* multi-byte characters untouched - it only removes device +* control codes +* @see http://hsivonen.iki.fi/producing-xml/#controlchar +* @param string +* @return string control codes removed +*/ +function utf8_strip_ascii_ctrl($str) +{ + ob_start(); + + while (preg_match('/^([^\x00-\x08\x0B\x0C\x0E-\x1F\x7F]+)|([\x00-\x08\x0B\x0C\x0E-\x1F\x7F]+)/S', $str, $matches)) + { + if (!isset($matches[2])) + echo $matches[0]; + + $str = substr($str, strlen($matches[0])); + } + + $result = ob_get_contents(); + ob_end_clean(); + + return $result; +} + +/** +* Strip out all non 7bit ASCII bytes and ASCII device control codes. +* For a list of ASCII device control codes see the 2nd table here: +* http://www.w3schools.com/tags/ref_ascii.asp +* +* @param string +* @return boolean TRUE if it's all ASCII +* @package utf8 +* @subpackage ascii +*/ +function utf8_strip_non_ascii_ctrl($str) +{ + ob_start(); + + while (preg_match( '/^([\x09\x0A\x0D\x20-\x7E]+)|([^\x09\x0A\x0D\x20-\x7E]+)/S', $str, $matches)) + { + if (!isset($matches[2])) + echo $matches[0]; + + $str = substr($str, strlen($matches[0])); + } + + $result = ob_get_contents(); + ob_end_clean(); + + return $result; +} + +/** +* Replace accented UTF-8 characters by unaccented ASCII-7 "equivalents". +* The purpose of this function is to replace characters commonly found in Latin +* alphabets with something more or less equivalent from the ASCII range. This can +* be useful for converting a UTF-8 to something ready for a filename, for example. +* Following the use of this function, you would probably also pass the string +* through utf8_strip_non_ascii to clean out any other non-ASCII chars +* Use the optional parameter to just deaccent lower ($case = -1) or upper ($case = 1) +* letters. Default is to deaccent both cases ($case = 0) +* +* For a more complete implementation of transliteration, see the utf8_to_ascii package +* available from the phputf8 project downloads: +* http://prdownloads.sourceforge.net/phputf8 +* +* @param string UTF-8 string +* @param int (optional) -1 lowercase only, +1 uppercase only, 1 both cases +* @param string UTF-8 with accented characters replaced by ASCII chars +* @return string accented chars replaced with ascii equivalents +* @author Andreas Gohr +* @package utf8 +* @subpackage ascii +*/ +function utf8_accents_to_ascii($str, $case=0) +{ + static $UTF8_LOWER_ACCENTS = null; + static $UTF8_UPPER_ACCENTS = null; + + if($case <= 0) + { + + if (is_null($UTF8_LOWER_ACCENTS)) + { + $UTF8_LOWER_ACCENTS = array( + 'à' => 'a', 'ô' => 'o', 'ď' => 'd', 'ḟ' => 'f', 'ë' => 'e', 'š' => 's', 'ơ' => 'o', + 'ß' => 'ss', 'ă' => 'a', 'ř' => 'r', 'ț' => 't', 'ň' => 'n', 'ā' => 'a', 'ķ' => 'k', + 'ŝ' => 's', 'ỳ' => 'y', 'ņ' => 'n', 'ĺ' => 'l', 'ħ' => 'h', 'ṗ' => 'p', 'ó' => 'o', + 'ú' => 'u', 'ě' => 'e', 'é' => 'e', 'ç' => 'c', 'ẁ' => 'w', 'ċ' => 'c', 'õ' => 'o', + 'ṡ' => 's', 'ø' => 'o', 'ģ' => 'g', 'ŧ' => 't', 'ș' => 's', 'ė' => 'e', 'ĉ' => 'c', + 'ś' => 's', 'î' => 'i', 'ű' => 'u', 'ć' => 'c', 'ę' => 'e', 'ŵ' => 'w', 'ṫ' => 't', + 'ū' => 'u', 'č' => 'c', 'ö' => 'oe', 'è' => 'e', 'ŷ' => 'y', 'ą' => 'a', 'ł' => 'l', + 'ų' => 'u', 'ů' => 'u', 'ş' => 's', 'ğ' => 'g', 'ļ' => 'l', 'ƒ' => 'f', 'ž' => 'z', + 'ẃ' => 'w', 'ḃ' => 'b', 'å' => 'a', 'ì' => 'i', 'ï' => 'i', 'ḋ' => 'd', 'ť' => 't', + 'ŗ' => 'r', 'ä' => 'ae', 'í' => 'i', 'ŕ' => 'r', 'ê' => 'e', 'ü' => 'ue', 'ò' => 'o', + 'ē' => 'e', 'ñ' => 'n', 'ń' => 'n', 'ĥ' => 'h', 'ĝ' => 'g', 'đ' => 'd', 'ĵ' => 'j', + 'ÿ' => 'y', 'ũ' => 'u', 'ŭ' => 'u', 'ư' => 'u', 'ţ' => 't', 'ý' => 'y', 'ő' => 'o', + 'â' => 'a', 'ľ' => 'l', 'ẅ' => 'w', 'ż' => 'z', 'ī' => 'i', 'ã' => 'a', 'ġ' => 'g', + 'ṁ' => 'm', 'ō' => 'o', 'ĩ' => 'i', 'ù' => 'u', 'į' => 'i', 'ź' => 'z', 'á' => 'a', + 'û' => 'u', 'þ' => 'th', 'ð' => 'dh', 'æ' => 'ae', 'µ' => 'u', 'ĕ' => 'e', + ); + } + + $str = str_replace(array_keys($UTF8_LOWER_ACCENTS), array_values($UTF8_LOWER_ACCENTS), $str); + } + + if($case >= 0) + { + if (is_null($UTF8_UPPER_ACCENTS)) + { + $UTF8_UPPER_ACCENTS = array( + 'À' => 'A', 'Ô' => 'O', 'Ď' => 'D', 'Ḟ' => 'F', 'Ë' => 'E', 'Š' => 'S', 'Ơ' => 'O', + 'Ă' => 'A', 'Ř' => 'R', 'Ț' => 'T', 'Ň' => 'N', 'Ā' => 'A', 'Ķ' => 'K', + 'Ŝ' => 'S', 'Ỳ' => 'Y', 'Ņ' => 'N', 'Ĺ' => 'L', 'Ħ' => 'H', 'Ṗ' => 'P', 'Ó' => 'O', + 'Ú' => 'U', 'Ě' => 'E', 'É' => 'E', 'Ç' => 'C', 'Ẁ' => 'W', 'Ċ' => 'C', 'Õ' => 'O', + 'Ṡ' => 'S', 'Ø' => 'O', 'Ģ' => 'G', 'Ŧ' => 'T', 'Ș' => 'S', 'Ė' => 'E', 'Ĉ' => 'C', + 'Ś' => 'S', 'Î' => 'I', 'Ű' => 'U', 'Ć' => 'C', 'Ę' => 'E', 'Ŵ' => 'W', 'Ṫ' => 'T', + 'Ū' => 'U', 'Č' => 'C', 'Ö' => 'Oe', 'È' => 'E', 'Ŷ' => 'Y', 'Ą' => 'A', 'Ł' => 'L', + 'Ų' => 'U', 'Ů' => 'U', 'Ş' => 'S', 'Ğ' => 'G', 'Ļ' => 'L', 'Ƒ' => 'F', 'Ž' => 'Z', + 'Ẃ' => 'W', 'Ḃ' => 'B', 'Å' => 'A', 'Ì' => 'I', 'Ï' => 'I', 'Ḋ' => 'D', 'Ť' => 'T', + 'Ŗ' => 'R', 'Ä' => 'Ae', 'Í' => 'I', 'Ŕ' => 'R', 'Ê' => 'E', 'Ü' => 'Ue', 'Ò' => 'O', + 'Ē' => 'E', 'Ñ' => 'N', 'Ń' => 'N', 'Ĥ' => 'H', 'Ĝ' => 'G', 'Đ' => 'D', 'Ĵ' => 'J', + 'Ÿ' => 'Y', 'Ũ' => 'U', 'Ŭ' => 'U', 'Ư' => 'U', 'Ţ' => 'T', 'Ý' => 'Y', 'Ő' => 'O', + 'Â' => 'A', 'Ľ' => 'L', 'Ẅ' => 'W', 'Ż' => 'Z', 'Ī' => 'I', 'Ã' => 'A', 'Ġ' => 'G', + 'Ṁ' => 'M', 'Ō' => 'O', 'Ĩ' => 'I', 'Ù' => 'U', 'Į' => 'I', 'Ź' => 'Z', 'Á' => 'A', + 'Û' => 'U', 'Þ' => 'Th', 'Ð' => 'Dh', 'Æ' => 'Ae', 'Ĕ' => 'E', + ); + } + + $str = str_replace(array_keys($UTF8_UPPER_ACCENTS), array_values($UTF8_UPPER_ACCENTS), $str); + } + + return $str; +} diff --git a/include/utf8/utils/bad.php b/include/utf8/utils/bad.php new file mode 100644 index 0000000..78e9d17 --- /dev/null +++ b/include/utf8/utils/bad.php @@ -0,0 +1,435 @@ + 0) + return $badList; + + return false; +} + +/** +* Strips out any bad bytes from a UTF-8 string and returns the rest +* PCRE Pattern to locate bad bytes in a UTF-8 string +* Comes from W3 FAQ: Multilingual Forms +* Note: modified to include full ASCII range including control chars +* @see http://www.w3.org/International/questions/qa-forms-utf-8 +* @param string +* @return string +* @package utf8 +* @subpackage bad +*/ +function utf8_bad_strip($str) +{ + $UTF8_BAD = + '([\x00-\x7F]'. # ASCII (including control chars) + '|[\xC2-\xDF][\x80-\xBF]'. # Non-overlong 2-byte + '|\xE0[\xA0-\xBF][\x80-\xBF]'. # Excluding overlongs + '|[\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}'. # Straight 3-byte + '|\xED[\x80-\x9F][\x80-\xBF]'. # Excluding surrogates + '|\xF0[\x90-\xBF][\x80-\xBF]{2}'. # Planes 1-3 + '|[\xF1-\xF3][\x80-\xBF]{3}'. # Planes 4-15 + '|\xF4[\x80-\x8F][\x80-\xBF]{2}'. # Plane 16 + '|(.{1}))'; # Invalid byte + + ob_start(); + + while (preg_match('/'.$UTF8_BAD.'/S', $str, $matches)) + { + if (!isset($matches[2])) + echo $matches[0]; + + $str = substr($str, strlen($matches[0])); + } + + $result = ob_get_contents(); + ob_end_clean(); + + return $result; +} + +/** +* Replace bad bytes with an alternative character - ASCII character +* recommended is replacement char +* PCRE Pattern to locate bad bytes in a UTF-8 string +* Comes from W3 FAQ: Multilingual Forms +* Note: modified to include full ASCII range including control chars +* @see http://www.w3.org/International/questions/qa-forms-utf-8 +* @param string to search +* @param string to replace bad bytes with (defaults to '?') - use ASCII +* @return string +* @package utf8 +* @subpackage bad +*/ +function utf8_bad_replace($str, $replace='?') +{ + $UTF8_BAD = + '([\x00-\x7F]'. # ASCII (including control chars) + '|[\xC2-\xDF][\x80-\xBF]'. # Non-overlong 2-byte + '|\xE0[\xA0-\xBF][\x80-\xBF]'. # Excluding overlongs + '|[\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}'. # Straight 3-byte + '|\xED[\x80-\x9F][\x80-\xBF]'. # Excluding surrogates + '|\xF0[\x90-\xBF][\x80-\xBF]{2}'. # Planes 1-3 + '|[\xF1-\xF3][\x80-\xBF]{3}'. # Planes 4-15 + '|\xF4[\x80-\x8F][\x80-\xBF]{2}'. # Plane 16 + '|(.{1}))'; # Invalid byte + + ob_start(); + + while (preg_match('/'.$UTF8_BAD.'/S', $str, $matches)) + { + if (!isset($matches[2])) + echo $matches[0]; + else + echo $replace; + + $str = substr($str, strlen($matches[0])); + } + + $result = ob_get_contents(); + ob_end_clean(); + + return $result; +} + +/** +* Return code from utf8_bad_identify() when a five octet sequence is detected. +* Note: 5 octets sequences are valid UTF-8 but are not supported by Unicode so +* do not represent a useful character +* @see utf8_bad_identify +* @package utf8 +* @subpackage bad +*/ +define('UTF8_BAD_5OCTET', 1); + +/** +* Return code from utf8_bad_identify() when a six octet sequence is detected. +* Note: 6 octets sequences are valid UTF-8 but are not supported by Unicode so +* do not represent a useful character +* @see utf8_bad_identify +* @package utf8 +* @subpackage bad +*/ +define('UTF8_BAD_6OCTET', 2); + +/** +* Return code from utf8_bad_identify(). +* Invalid octet for use as start of multi-byte UTF-8 sequence +* @see utf8_bad_identify +* @package utf8 +* @subpackage bad +*/ +define('UTF8_BAD_SEQID', 3); + +/** +* Return code from utf8_bad_identify(). +* From Unicode 3.1, non-shortest form is illegal +* @see utf8_bad_identify +* @package utf8 +* @subpackage bad +*/ +define('UTF8_BAD_NONSHORT', 4); + +/** +* Return code from utf8_bad_identify(). +* From Unicode 3.2, surrogate characters are illegal +* @see utf8_bad_identify +* @package utf8 +* @subpackage bad +*/ +define('UTF8_BAD_SURROGATE', 5); + +/** +* Return code from utf8_bad_identify(). +* Codepoints outside the Unicode range are illegal +* @see utf8_bad_identify +* @package utf8 +* @subpackage bad +*/ +define('UTF8_BAD_UNIOUTRANGE', 6); + +/** +* Return code from utf8_bad_identify(). +* Incomplete multi-octet sequence +* Note: this is kind of a "catch-all" +* @see utf8_bad_identify +* @package utf8 +* @subpackage bad +*/ +define('UTF8_BAD_SEQINCOMPLETE', 7); + +/** +* Reports on the type of bad byte found in a UTF-8 string. Returns a +* status code on the first bad byte found +* @author +* @param string UTF-8 encoded string +* @return mixed integer constant describing problem or FALSE if valid UTF-8 +* @see utf8_bad_explain +* @see http://hsivonen.iki.fi/php-utf8/ +* @package utf8 +* @subpackage bad +*/ +function utf8_bad_identify($str, &$i) +{ + $mState = 0; // Cached expected number of octets after the current octet + // until the beginning of the next UTF8 character sequence + $mUcs4 = 0; // Cached Unicode character + $mBytes = 1; // Cached expected number of octets in the current sequence + + $len = strlen($str); + + for($i=0; $i < $len; $i++) + { + $in = ord($str{$i}); + + if ( $mState == 0) + { + // When mState is zero we expect either a US-ASCII character or a multi-octet sequence. + if (0 == (0x80 & ($in))) + { + // US-ASCII, pass straight through. + $mBytes = 1; + } + else if (0xC0 == (0xE0 & ($in))) + { + // First octet of 2 octet sequence + $mUcs4 = ($in); + $mUcs4 = ($mUcs4 & 0x1F) << 6; + $mState = 1; + $mBytes = 2; + } + else if (0xE0 == (0xF0 & ($in))) + { + // First octet of 3 octet sequence + $mUcs4 = ($in); + $mUcs4 = ($mUcs4 & 0x0F) << 12; + $mState = 2; + $mBytes = 3; + } + else if (0xF0 == (0xF8 & ($in))) + { + // First octet of 4 octet sequence + $mUcs4 = ($in); + $mUcs4 = ($mUcs4 & 0x07) << 18; + $mState = 3; + $mBytes = 4; + } + else if (0xF8 == (0xFC & ($in))) + { + /* First octet of 5 octet sequence. + * + * This is illegal because the encoded codepoint must be either + * (a) not the shortest form or + * (b) outside the Unicode range of 0-0x10FFFF. + */ + return UTF8_BAD_5OCTET; + } + else if (0xFC == (0xFE & ($in))) + { + // First octet of 6 octet sequence, see comments for 5 octet sequence. + return UTF8_BAD_6OCTET; + } + else + { + // Current octet is neither in the US-ASCII range nor a legal first + // octet of a multi-octet sequence. + return UTF8_BAD_SEQID; + } + } + else + { + // When mState is non-zero, we expect a continuation of the multi-octet sequence + if (0x80 == (0xC0 & ($in))) + { + // Legal continuation. + $shift = ($mState - 1) * 6; + $tmp = $in; + $tmp = ($tmp & 0x0000003F) << $shift; + $mUcs4 |= $tmp; + + /** + * End of the multi-octet sequence. mUcs4 now contains the final + * Unicode codepoint to be output + */ + if (0 == --$mState) + { + // From Unicode 3.1, non-shortest form is illegal + if (((2 == $mBytes) && ($mUcs4 < 0x0080)) || + ((3 == $mBytes) && ($mUcs4 < 0x0800)) || + ((4 == $mBytes) && ($mUcs4 < 0x10000)) ) + return UTF8_BAD_NONSHORT; + else if (($mUcs4 & 0xFFFFF800) == 0xD800) // From Unicode 3.2, surrogate characters are illegal + return UTF8_BAD_SURROGATE; + else if ($mUcs4 > 0x10FFFF) // Codepoints outside the Unicode range are illegal + return UTF8_BAD_UNIOUTRANGE; + + // Initialize UTF8 cache + $mState = 0; + $mUcs4 = 0; + $mBytes = 1; + } + + } + else + { + // ((0xC0 & (*in) != 0x80) && (mState != 0)) + // Incomplete multi-octet sequence. + $i--; + return UTF8_BAD_SEQINCOMPLETE; + } + } + } + + // Incomplete multi-octet sequence + if ($mState != 0) + { + $i--; + return UTF8_BAD_SEQINCOMPLETE; + } + + // No bad octets found + $i = null; + return false; +} + +/** +* Takes a return code from utf8_bad_identify() are returns a message +* (in English) explaining what the problem is. +* @param int return code from utf8_bad_identify +* @return mixed string message or FALSE if return code unknown +* @see utf8_bad_identify +* @package utf8 +* @subpackage bad +*/ +function utf8_bad_explain($code) +{ + switch ($code) + { + case UTF8_BAD_5OCTET: + return 'Five octet sequences are valid UTF-8 but are not supported by Unicode'; + break; + + case UTF8_BAD_6OCTET: + return 'Six octet sequences are valid UTF-8 but are not supported by Unicode'; + break; + + case UTF8_BAD_SEQID: + return 'Invalid octet for use as start of multi-byte UTF-8 sequence'; + break; + + case UTF8_BAD_NONSHORT: + return 'From Unicode 3.1, non-shortest form is illegal'; + break; + + case UTF8_BAD_SURROGATE: + return 'From Unicode 3.2, surrogate characters are illegal'; + break; + + case UTF8_BAD_UNIOUTRANGE: + return 'Codepoints outside the Unicode range are illegal'; + break; + + case UTF8_BAD_SEQINCOMPLETE: + return 'Incomplete multi-octet sequence'; + break; + } + + trigger_error('Unknown error code: '.$code, E_USER_WARNING); + + return false; +} diff --git a/include/utf8/utils/index.html b/include/utf8/utils/index.html new file mode 100644 index 0000000..89337b2 --- /dev/null +++ b/include/utf8/utils/index.html @@ -0,0 +1 @@ +.. diff --git a/include/utf8/utils/patterns.php b/include/utf8/utils/patterns.php new file mode 100644 index 0000000..5a85a4f --- /dev/null +++ b/include/utf8/utils/patterns.php @@ -0,0 +1,67 @@ + +* @param string string to locate index in +* @param int (n times) +* @return mixed - int if only one input int, array if more +* @return boolean TRUE if it's all ASCII +* @package utf8 +* @subpackage position +*/ +function utf8_byte_position() +{ + $args = func_get_args(); + $str =& array_shift($args); + + if (!is_string($str)) + return false; + + $result = array(); + $prev = array(0, 0); // Trivial byte index, character offset pair + $i = utf8_locate_next_chr($str, 300); // Use a short piece of str to estimate bytes per character. $i (& $j) -> byte indexes into $str + $c = strlen(utf8_decode(substr($str, 0, $i))); // $c -> character offset into $str + + // Deal with arguments from lowest to highest + sort($args); + + foreach ($args as $offset) + { + // Sanity checks FIXME + + // 0 is an easy check + if ($offset == 0) + { + $result[] = 0; continue; + } + + // Ensure no endless looping + $safety_valve = 50; + + do + { + if (($c - $prev[1]) == 0) + { + // Hack: gone past end of string + $error = 0; + $i = strlen($str); + break; + } + + $j = $i + (int)(($offset-$c) * ($i - $prev[0]) / ($c - $prev[1])); + $j = utf8_locate_next_chr($str, $j); // Correct to utf8 character boundary + $prev = array($i,$c); // Save the index, offset for use next iteration + + if ($j > $i) + $c += strlen(utf8_decode(substr($str, $i, $j-$i))); // Determine new character offset + else + $c -= strlen(utf8_decode(substr($str, $j, $i-$j))); // Ditto + + $error = abs($c-$offset); + $i = $j; // Ready for next time around + } + while (($error > 7) && --$safety_valve); // From 7 it is faster to iterate over the string + + if ($error && $error <= 7) + { + if ($c < $offset) + { + // Move up + while ($error--) + $i = utf8_locate_next_chr($str, ++$i); + } + else + { + // Move down + while ($error--) + $i = utf8_locate_current_chr($str, --$i); + } + + // Ready for next arg + $c = $offset; + } + + $result[] = $i; + } + + if (count($result) == 1) + return $result[0]; + + return $result; +} + +/** +* Given a string and any byte index, returns the byte index +* of the start of the current UTF-8 character, relative to supplied +* position. If the current character begins at the same place as the +* supplied byte index, that byte index will be returned. Otherwise +* this function will step backwards, looking for the index where +* curent UTF-8 character begins +* @author Chris Smith +* @param string +* @param int byte index in the string +* @return int byte index of start of next UTF-8 character +* @package utf8 +* @subpackage position +*/ +function utf8_locate_current_chr( &$str, $idx ) +{ + if ($idx <= 0) + return 0; + + $limit = strlen($str); + if ($idx >= $limit) + return $limit; + + // Binary value for any byte after the first in a multi-byte UTF-8 character + // will be like 10xxxxxx so & 0xC0 can be used to detect this kind + // of byte - assuming well formed UTF-8 + while ($idx && ((ord($str[$idx]) & 0xC0) == 0x80)) + $idx--; + + return $idx; +} + +/** +* Given a string and any byte index, returns the byte index +* of the start of the next UTF-8 character, relative to supplied +* position. If the next character begins at the same place as the +* supplied byte index, that byte index will be returned. +* @author Chris Smith +* @param string +* @param int byte index in the string +* @return int byte index of start of next UTF-8 character +* @package utf8 +* @subpackage position +*/ +function utf8_locate_next_chr(&$str, $idx) +{ + if ($idx <= 0) + return 0; + + $limit = strlen($str); + if ($idx >= $limit) + return $limit; + + // Binary value for any byte after the first in a multi-byte UTF-8 character + // will be like 10xxxxxx so & 0xC0 can be used to detect this kind + // of byte - assuming well formed UTF-8 + while (($idx < $limit) && ((ord($str[$idx]) & 0xC0) == 0x80)) + $idx++; + + return $idx; +} diff --git a/include/utf8/utils/specials.php b/include/utf8/utils/specials.php new file mode 100644 index 0000000..69219dc --- /dev/null +++ b/include/utf8/utils/specials.php @@ -0,0 +1,131 @@ + +* @param string $string The UTF8 string to strip of special chars +* @param string (optional) $repl Replace special with this string +* @return string with common non-alphanumeric characters removed +* @see utf8_specials_pattern +*/ +function utf8_strip_specials($string, $repl='') +{ + return preg_replace(utf8_specials_pattern(), $repl, $string); +} diff --git a/include/utf8/utils/unicode.php b/include/utf8/utils/unicode.php new file mode 100644 index 0000000..f0e86cb --- /dev/null +++ b/include/utf8/utils/unicode.php @@ -0,0 +1,241 @@ + 0xFFFF. Occurrances of the BOM are ignored. Surrogates +* are not allowed. +* Returns false if the input string isn't a valid UTF-8 octet sequence +* and raises a PHP error at level E_USER_WARNING +* Note: this function has been modified slightly in this library to +* trigger errors on encountering bad bytes +* @author +* @param string UTF-8 encoded string +* @return mixed array of unicode code points or FALSE if UTF-8 invalid +* @see utf8_from_unicode +* @see http://hsivonen.iki.fi/php-utf8/ +* @package utf8 +* @subpackage unicode +*/ +function utf8_to_unicode($str) +{ + $mState = 0; // Cached expected number of octets after the current octet + // until the beginning of the next UTF8 character sequence + $mUcs4 = 0; // Cached Unicode character + $mBytes = 1; // Cached expected number of octets in the current sequence + + $out = array(); + $len = strlen($str); + + for($i = 0; $i < $len; $i++) + { + $in = ord($str[$i]); + + if ($mState == 0) + { + // When mState is zero we expect either a US-ASCII character or a multi-octet sequence. + if (0 == (0x80 & ($in))) + { + // US-ASCII, pass straight through. + $out[] = $in; + $mBytes = 1; + } + else if (0xC0 == (0xE0 & ($in))) + { + // First octet of 2 octet sequence + $mUcs4 = ($in); + $mUcs4 = ($mUcs4 & 0x1F) << 6; + $mState = 1; + $mBytes = 2; + } + else if (0xE0 == (0xF0 & ($in))) + { + // First octet of 3 octet sequence + $mUcs4 = ($in); + $mUcs4 = ($mUcs4 & 0x0F) << 12; + $mState = 2; + $mBytes = 3; + } + else if (0xF0 == (0xF8 & ($in))) + { + // First octet of 4 octet sequence + $mUcs4 = ($in); + $mUcs4 = ($mUcs4 & 0x07) << 18; + $mState = 3; + $mBytes = 4; + } + else if (0xF8 == (0xFC & ($in))) + { + /* First octet of 5 octet sequence. + * + * This is illegal because the encoded codepoint must be either + * (a) not the shortest form or + * (b) outside the Unicode range of 0-0x10FFFF. + * Rather than trying to resynchronize, we will carry on until the end + * of the sequence and let the later error handling code catch it. + */ + $mUcs4 = ($in); + $mUcs4 = ($mUcs4 & 0x03) << 24; + $mState = 4; + $mBytes = 5; + } + else if (0xFC == (0xFE & ($in))) + { + // First octet of 6 octet sequence, see comments for 5 octet sequence. + $mUcs4 = ($in); + $mUcs4 = ($mUcs4 & 1) << 30; + $mState = 5; + $mBytes = 6; + } + else + { + // Current octet is neither in the US-ASCII range nor a legal first octet of a multi-octet sequence + trigger_error('utf8_to_unicode: Illegal sequence identifier in UTF-8 at byte '.$i, E_USER_WARNING); + return false; + } + } + else + { + // When mState is non-zero, we expect a continuation of the multi-octet sequence + if (0x80 == (0xC0 & ($in))) + { + // Legal continuation. + $shift = ($mState - 1) * 6; + $tmp = $in; + $tmp = ($tmp & 0x0000003F) << $shift; + $mUcs4 |= $tmp; + + /** + * End of the multi-octet sequence. mUcs4 now contains the final + * Unicode codepoint to be output + */ + if (0 == --$mState) + { + /* + * Check for illegal sequences and codepoints. + */ + // From Unicode 3.1, non-shortest form is illegal + if (((2 == $mBytes) && ($mUcs4 < 0x0080)) || ((3 == $mBytes) && ($mUcs4 < 0x0800)) || + ((4 == $mBytes) && ($mUcs4 < 0x10000)) || (4 < $mBytes) || + // From Unicode 3.2, surrogate characters are illegal + (($mUcs4 & 0xFFFFF800) == 0xD800) || + // Codepoints outside the Unicode range are illegal + ($mUcs4 > 0x10FFFF)) + { + trigger_error('utf8_to_unicode: Illegal sequence or codepoint in UTF-8 at byte '.$i, E_USER_WARNING); + return false; + } + + // BOM is legal but we don't want to output it + if (0xFEFF != $mUcs4) + $out[] = $mUcs4; + + // Initialize UTF8 cache + $mState = 0; + $mUcs4 = 0; + $mBytes = 1; + } + + } + else + { + /* ((0xC0 & (*in) != 0x80) && (mState != 0)) + Incomplete multi-octet sequence. */ + trigger_error('utf8_to_unicode: Incomplete multi-octet sequence in UTF-8 at byte '.$i, E_USER_WARNING); + return false; + } + } + } + + return $out; +} + +/** +* Takes an array of ints representing the Unicode characters and returns +* a UTF-8 string. Astral planes are supported ie. the ints in the +* input can be > 0xFFFF. Occurrances of the BOM are ignored. Surrogates +* are not allowed. +* Returns false if the input array contains ints that represent +* surrogates or are outside the Unicode range +* and raises a PHP error at level E_USER_WARNING +* Note: this function has been modified slightly in this library to use +* output buffering to concatenate the UTF-8 string (faster) as well as +* reference the array by it's keys +* @param array of unicode code points representing a string +* @return mixed UTF-8 string or FALSE if array contains invalid code points +* @author +* @see utf8_to_unicode +* @see http://hsivonen.iki.fi/php-utf8/ +* @package utf8 +* @subpackage unicode +*/ +function utf8_from_unicode($arr) +{ + ob_start(); + + foreach (array_keys($arr) as $k) + { + if ( ($arr[$k] >= 0) && ($arr[$k] <= 0x007f) ) // ASCII range (including control chars) + { + echo chr($arr[$k]); + } + else if ($arr[$k] <= 0x07ff) //2 byte sequence + { + echo chr(0xc0 | ($arr[$k] >> 6)); + echo chr(0x80 | ($arr[$k] & 0x003f)); + } + else if($arr[$k] == 0xFEFF) // Byte order mark (skip) + { + // Nop -- zap the BOM + } + else if ($arr[$k] >= 0xD800 && $arr[$k] <= 0xDFFF) // Test for illegal surrogates + { + // Found a surrogate + trigger_error('utf8_from_unicode: Illegal surrogate at index: '.$k.', value: '.$arr[$k], E_USER_WARNING); + + return false; + } + else if ($arr[$k] <= 0xffff) // 3 byte sequence + { + echo chr(0xe0 | ($arr[$k] >> 12)); + echo chr(0x80 | (($arr[$k] >> 6) & 0x003f)); + echo chr(0x80 | ($arr[$k] & 0x003f)); + } + else if ($arr[$k] <= 0x10ffff) // 4 byte sequence + { + echo chr(0xf0 | ($arr[$k] >> 18)); + echo chr(0x80 | (($arr[$k] >> 12) & 0x3f)); + echo chr(0x80 | (($arr[$k] >> 6) & 0x3f)); + echo chr(0x80 | ($arr[$k] & 0x3f)); + } + else + { + trigger_error('utf8_from_unicode: Codepoint out of Unicode range at index: '.$k.', value: '.$arr[$k], E_USER_WARNING); + + // Out of range + return false; + } + } + + $result = ob_get_contents(); + ob_end_clean(); + + return $result; +} diff --git a/include/utf8/utils/validation.php b/include/utf8/utils/validation.php new file mode 100644 index 0000000..90dce8e --- /dev/null +++ b/include/utf8/utils/validation.php @@ -0,0 +1,186 @@ + +* @param string UTF-8 encoded string +* @return boolean true if valid +* @see http://hsivonen.iki.fi/php-utf8/ +* @see utf8_compliant +* @package utf8 +* @subpackage validation +*/ +function utf8_is_valid($str) +{ + $mState = 0; // Cached expected number of octets after the current octet + // until the beginning of the next UTF8 character sequence + $mUcs4 = 0; // Cached Unicode character + $mBytes = 1; // Cached expected number of octets in the current sequence + + $len = strlen($str); + + for($i = 0; $i < $len; $i++) + { + $in = ord($str{$i}); + + if ( $mState == 0) + { + // When mState is zero we expect either a US-ASCII character or a multi-octet sequence. + if (0 == (0x80 & ($in))) + { + $mBytes = 1; // US-ASCII, pass straight through + } + else if (0xC0 == (0xE0 & ($in))) + { + // First octet of 2 octet sequence + $mUcs4 = ($in); + $mUcs4 = ($mUcs4 & 0x1F) << 6; + $mState = 1; + $mBytes = 2; + } + else if (0xE0 == (0xF0 & ($in))) + { + // First octet of 3 octet sequence + $mUcs4 = ($in); + $mUcs4 = ($mUcs4 & 0x0F) << 12; + $mState = 2; + $mBytes = 3; + } + else if (0xF0 == (0xF8 & ($in))) + { + // First octet of 4 octet sequence + $mUcs4 = ($in); + $mUcs4 = ($mUcs4 & 0x07) << 18; + $mState = 3; + $mBytes = 4; + } + else if (0xF8 == (0xFC & ($in))) + { + /* First octet of 5 octet sequence. + * + * This is illegal because the encoded codepoint must be either + * (a) not the shortest form or + * (b) outside the Unicode range of 0-0x10FFFF. + * Rather than trying to resynchronize, we will carry on until the end + * of the sequence and let the later error handling code catch it. + */ + $mUcs4 = ($in); + $mUcs4 = ($mUcs4 & 0x03) << 24; + $mState = 4; + $mBytes = 5; + } + else if (0xFC == (0xFE & ($in))) + { + // First octet of 6 octet sequence, see comments for 5 octet sequence. + $mUcs4 = ($in); + $mUcs4 = ($mUcs4 & 1) << 30; + $mState = 5; + $mBytes = 6; + } + else + { + // Current octet is neither in the US-ASCII range nor a legal first octet of a multi-octet sequence. + return false; + } + } + else + { + // When mState is non-zero, we expect a continuation of the multi-octet sequence + if (0x80 == (0xC0 & ($in))) + { + // Legal continuation. + $shift = ($mState - 1) * 6; + $tmp = $in; + $tmp = ($tmp & 0x0000003F) << $shift; + $mUcs4 |= $tmp; + + /** + * End of the multi-octet sequence. mUcs4 now contains the final + * Unicode codepoint to be output + */ + if (0 == --$mState) + { + /* + * Check for illegal sequences and codepoints. + */ + // From Unicode 3.1, non-shortest form is illegal + if (((2 == $mBytes) && ($mUcs4 < 0x0080)) || ((3 == $mBytes) && ($mUcs4 < 0x0800)) || + ((4 == $mBytes) && ($mUcs4 < 0x10000)) || (4 < $mBytes) || + // From Unicode 3.2, surrogate characters are illegal + (($mUcs4 & 0xFFFFF800) == 0xD800) || + // Codepoints outside the Unicode range are illegal + ($mUcs4 > 0x10FFFF)) + { + return FALSE; + } + + // Initialize UTF8 cache + $mState = 0; + $mUcs4 = 0; + $mBytes = 1; + } + } + else + { + /** + *((0xC0 & (*in) != 0x80) && (mState != 0)) + * Incomplete multi-octet sequence. + */ + + return false; + } + } + } + + return true; +} + +/** +* Tests whether a string complies as UTF-8. This will be much +* faster than utf8_is_valid, but will pass five and six octet +* UTF-8 sequences, which are not supported by Unicode and +* so cannot be displayed correctly in a browser. In other words +* it is not as strict as utf8_is_valid but it's faster. If you use +* is to validate user input, you place yourself at the risk that +* attackers will be able to inject 5 and 6 byte sequences (which +* may or may not be a significant risk, depending on what you are +* are doing) +* Note: Does not pass five and six octet UTF-8 sequences anymore in +* in the unit tests. +* @see utf8_is_valid +* @see http://www.php.net/manual/en/reference.pcre.pattern.modifiers.php#54805 +* @param string UTF-8 string to check +* @return boolean TRUE if string is valid UTF-8 +* @package utf8 +* @subpackage validation +*/ +function utf8_compliant($str) +{ + if (strlen($str) == 0) + return true; + + // If even just the first character can be matched, when the /u + // modifier is used, then it's valid UTF-8. If the UTF-8 is somehow + // invalid, nothing at all will match, even if the string contains + // some valid sequences + return (preg_match('/^.{1}/us', $str, $ar) == 1); +} diff --git a/index.php b/index.php new file mode 100644 index 0000000..1dccb94 --- /dev/null +++ b/index.php @@ -0,0 +1,241 @@ +query('SELECT t.forum_id, t.id, t.last_post FROM '.$db->prefix.'topics AS t INNER JOIN '.$db->prefix.'forums AS f ON f.id=t.forum_id LEFT JOIN '.$db->prefix.'forum_perms AS fp ON (fp.forum_id=f.id AND fp.group_id='.$pun_user['g_id'].') WHERE (fp.read_forum IS NULL OR fp.read_forum=1) AND t.last_post>'.$pun_user['last_visit'].' AND t.moved_to IS NULL') or error('Unable to fetch new topics', __FILE__, __LINE__, $db->error()); + + $new_topics = array(); + while ($cur_topic = $db->fetch_assoc($result)) + $new_topics[$cur_topic['forum_id']][$cur_topic['id']] = $cur_topic['last_post']; + + $tracked_topics = get_tracked_topics(); +} + +if ($pun_config['o_feed_type'] == '1') + $page_head = array('feed' => ''); +else if ($pun_config['o_feed_type'] == '2') + $page_head = array('feed' => ''); + +$page_title = array(pun_htmlspecialchars($pun_config['o_board_title'])); +define('PUN_ALLOW_INDEX', 1); +define('PUN_ACTIVE_PAGE', 'index'); +require PUN_ROOT.'header.php'; + +// Print the categories and forums +$result = $db->query('SELECT c.id AS cid, c.cat_name, f.id AS fid, f.forum_name, f.forum_desc, f.redirect_url, f.moderators, f.num_topics, f.num_posts, f.last_post, f.last_post_id, f.last_poster FROM '.$db->prefix.'categories AS c INNER JOIN '.$db->prefix.'forums AS f ON c.id=f.cat_id LEFT JOIN '.$db->prefix.'forum_perms AS fp ON (fp.forum_id=f.id AND fp.group_id='.$pun_user['g_id'].') WHERE fp.read_forum IS NULL OR fp.read_forum=1 ORDER BY c.disp_position, c.id, f.disp_position', true) or error('Unable to fetch category/forum list', __FILE__, __LINE__, $db->error()); + +$cur_category = 0; +$cat_count = 0; +$forum_count = 0; +while ($cur_forum = $db->fetch_assoc($result)) +{ + $moderators = ''; + + if ($cur_forum['cid'] != $cur_category) // A new category since last iteration? + { + if ($cur_category != 0) + echo "\t\t\t".''."\n\t\t\t".''."\n\t\t".'
    '."\n\t".'
    '."\n".'
    '."\n\n"; + + ++$cat_count; + $forum_count = 0; + +?> +
    +

    +
    +
    + + + + + + + + + + + $pun_user['last_visit'] && (empty($tracked_topics['forums'][$cur_forum['fid']]) || $cur_forum['last_post'] > $tracked_topics['forums'][$cur_forum['fid']])) + { + // There are new posts in this forum, but have we read all of them already? + foreach ($new_topics[$cur_forum['fid']] as $check_topic_id => $check_last_post) + { + if ((empty($tracked_topics['topics'][$check_topic_id]) || $tracked_topics['topics'][$check_topic_id] < $check_last_post) && (empty($tracked_topics['forums'][$cur_forum['fid']]) || $tracked_topics['forums'][$cur_forum['fid']] < $check_last_post)) + { + $item_status .= ' inew'; + $forum_field_new = '[ '.$lang_common['New posts'].' ]'; + $icon_type = 'icon icon-new'; + + break; + } + } + } + + // Is this a redirect forum? + if ($cur_forum['redirect_url'] != '') + { + $forum_field = '

    '.$lang_index['Link to'].' '.pun_htmlspecialchars($cur_forum['forum_name']).'

    '; + $num_topics = $num_posts = '-'; + $item_status .= ' iredirect'; + $icon_type = 'icon'; + } + else + { + $forum_field = '

    '.pun_htmlspecialchars($cur_forum['forum_name']).''.(!empty($forum_field_new) ? ' '.$forum_field_new : '').'

    '; + $num_topics = $cur_forum['num_topics']; + $num_posts = $cur_forum['num_posts']; + } + + if ($cur_forum['forum_desc'] != '') + $forum_field .= "\n\t\t\t\t\t\t\t\t".'
    '.$cur_forum['forum_desc'].'
    '; + + // If there is a last_post/last_poster + if ($cur_forum['last_post'] != '') + $last_post = ''.format_time($cur_forum['last_post']).''.$lang_common['by'].' '.pun_htmlspecialchars($cur_forum['last_poster']).''; + else if ($cur_forum['redirect_url'] != '') + $last_post = '- - -'; + else + $last_post = $lang_common['Never']; + + if ($cur_forum['moderators'] != '') + { + $mods_array = unserialize($cur_forum['moderators']); + $moderators = array(); + + foreach ($mods_array as $mod_username => $mod_id) + { + if ($pun_user['g_view_users'] == '1') + $moderators[] = ''.pun_htmlspecialchars($mod_username).''; + else + $moderators[] = pun_htmlspecialchars($mod_username); + } + + $moderators = "\t\t\t\t\t\t\t\t".'

    ('.$lang_common['Moderated by'].' '.implode(', ', $moderators).')

    '."\n"; + } + +?> + + + + + + + 0) + echo "\t\t\t".''."\n\t\t\t".'
    +
    +
    +
    + +
    +
    +
    '."\n\t\t".'
    '."\n\t".'
    '."\n".'
    '."\n\n"; +else + echo '

    '.$lang_index['Empty board'].'

    '; + + +// Collect some statistics from the database +$result = $db->query('SELECT COUNT(id)-1 FROM '.$db->prefix.'users WHERE group_id!='.PUN_UNVERIFIED) or error('Unable to fetch total user count', __FILE__, __LINE__, $db->error()); +$stats['total_users'] = $db->result($result); + +$result = $db->query('SELECT id, username FROM '.$db->prefix.'users WHERE group_id!='.PUN_UNVERIFIED.' ORDER BY registered DESC LIMIT 1') or error('Unable to fetch newest registered user', __FILE__, __LINE__, $db->error()); +$stats['last_user'] = $db->fetch_assoc($result); + +$result = $db->query('SELECT SUM(num_topics), SUM(num_posts) FROM '.$db->prefix.'forums') or error('Unable to fetch topic/post count', __FILE__, __LINE__, $db->error()); +list($stats['total_topics'], $stats['total_posts']) = $db->fetch_row($result); + +if ($pun_user['g_view_users'] == '1') + $stats['newest_user'] = ''.pun_htmlspecialchars($stats['last_user']['username']).''; +else + $stats['newest_user'] = pun_htmlspecialchars($stats['last_user']['username']); + +?> +
    +

    +
    +
    +
    +
    +
    '.forum_number_format($stats['total_users']).'') ?>
    +
    '.forum_number_format($stats['total_topics']).'') ?>
    +
    '.forum_number_format($stats['total_posts']).'') ?>
    +
    +
    +
    +
    +query('SELECT user_id, ident FROM '.$db->prefix.'online WHERE idle=0 ORDER BY ident', true) or error('Unable to fetch online list', __FILE__, __LINE__, $db->error()); + + while ($pun_user_online = $db->fetch_assoc($result)) + { + if ($pun_user_online['user_id'] > 1) + { + if ($pun_user['g_view_users'] == '1') + $users[] = "\n\t\t\t\t".'
    '.pun_htmlspecialchars($pun_user_online['ident']).''; + else + $users[] = "\n\t\t\t\t".'
    '.pun_htmlspecialchars($pun_user_online['ident']); + } + else + ++$num_guests; + } + + $num_users = count($users); + echo "\t\t\t\t".'
    '.sprintf($lang_index['Users online'], ''.forum_number_format($num_users).'').'
    '."\n\t\t\t\t".'
    '.sprintf($lang_index['Guests online'], ''.forum_number_format($num_guests).'').'
    '."\n\t\t\t".'
    '."\n"; + + + if ($num_users > 0) + echo "\t\t\t".'
    '."\n\t\t\t\t".'
    '.$lang_index['Online'].'
    '."\t\t\t\t".implode(', ', $users).''."\n\t\t\t".'
    '."\n"; + else + echo "\t\t\t".'
    '."\n"; + +} +else + echo "\t\t\t".''."\n\t\t\t".'
    '."\n"; + + +?> +
    +
    +
    +here instead.'); +} + +// Define PUN because email.php requires it +define('PUN', 1); + +// Make sure we are running at least MIN_PHP_VERSION +if (!function_exists('version_compare') || version_compare(PHP_VERSION, MIN_PHP_VERSION, '<')) + exit('You are running PHP version '.PHP_VERSION.'. FluxBB '.FORUM_VERSION.' requires at least PHP '.MIN_PHP_VERSION.' to run properly. You must upgrade your PHP installation before you can continue.'); + +// Load the functions script +require PUN_ROOT.'include/functions.php'; + +// Load UTF-8 functions +require PUN_ROOT.'include/utf8/utf8.php'; + +// Strip out "bad" UTF-8 characters +forum_remove_bad_characters(); + +// Reverse the effect of register_globals +forum_unregister_globals(); + +// Disable error reporting for uninitialized variables +error_reporting(E_ALL); + +// Force POSIX locale (to prevent functions such as strtolower() from messing up UTF-8 strings) +setlocale(LC_CTYPE, 'C'); + +// Turn off magic_quotes_runtime +if (get_magic_quotes_runtime()) + set_magic_quotes_runtime(0); + +// Strip slashes from GET/POST/COOKIE (if magic_quotes_gpc is enabled) +if (get_magic_quotes_gpc()) +{ + function stripslashes_array($array) + { + return is_array($array) ? array_map('stripslashes_array', $array) : stripslashes($array); + } + + $_GET = stripslashes_array($_GET); + $_POST = stripslashes_array($_POST); + $_COOKIE = stripslashes_array($_COOKIE); + $_REQUEST = stripslashes_array($_REQUEST); +} + +// Turn off PHP time limit +@set_time_limit(0); + +// +// Generate output to be used for config.php +// +function generate_config_file() +{ + global $db_type, $db_host, $db_name, $db_username, $db_password, $db_prefix, $cookie_name, $cookie_seed; + + return 'Unfortunately no one can be told what FluxBB is - you have to see it for yourself.

    '; + $default_lang = 'English'; + $default_style = 'Air'; +} +else +{ + $db_type = $_POST['req_db_type']; + $db_host = pun_trim($_POST['req_db_host']); + $db_name = pun_trim($_POST['req_db_name']); + $db_username = pun_trim($_POST['db_username']); + $db_password = pun_trim($_POST['db_password']); + $db_prefix = pun_trim($_POST['db_prefix']); + $username = pun_trim($_POST['req_username']); + $email = strtolower(pun_trim($_POST['req_email'])); + $password1 = pun_trim($_POST['req_password1']); + $password2 = pun_trim($_POST['req_password2']); + $title = pun_trim($_POST['req_title']); + $description = pun_trim($_POST['desc']); + $base_url = pun_trim($_POST['req_base_url']); + $default_lang = pun_trim($_POST['req_default_lang']); + $default_style = pun_trim($_POST['req_default_style']); + $alerts = array(); + + // Make sure base_url doesn't end with a slash + if (substr($base_url, -1) == '/') + $base_url = substr($base_url, 0, -1); + + // Validate username and passwords + if (pun_strlen($username) < 2) + $alerts[] = 'Usernames must be at least 2 characters long.'; + else if (pun_strlen($username) > 25) // This usually doesn't happen since the form element only accepts 25 characters + $alerts[] = 'Usernames must not be more than 25 characters long.'; + else if (!strcasecmp($username, 'Guest')) + $alerts[] = 'The username guest is reserved.'; + else if (preg_match('/[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}/', $username) || preg_match('/((([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}:[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){5}:([0-9A-Fa-f]{1,4}:)?[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){4}:([0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){3}:([0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){2}:([0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|(([0-9A-Fa-f]{1,4}:){0,5}:((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|(::([0-9A-Fa-f]{1,4}:){0,5}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|([0-9A-Fa-f]{1,4}::([0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})|(::([0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){1,7}:))/', $username)) + $alerts[] = 'Usernames may not be in the form of an IP address.'; + else if ((strpos($username, '[') !== false || strpos($username, ']') !== false) && strpos($username, '\'') !== false && strpos($username, '"') !== false) + $alerts[] = 'Usernames may not contain all the characters \', " and [ or ] at once.'; + else if (preg_match('/(?:\[\/?(?:b|u|i|h|colou?r|quote|code|img|url|email|list)\]|\[(?:code|quote|list)=)/i', $username)) + $alerts[] = 'Usernames may not contain any of the text formatting tags (BBCode) that the forum uses.'; + + if (pun_strlen($password1) < 4) + $alerts[] = 'Passwords must be at least 4 characters long.'; + else if ($password1 != $password2) + $alerts[] = 'Passwords do not match.'; + + // Validate email + require PUN_ROOT.'include/email.php'; + + if (!is_valid_email($email)) + $alerts[] = 'The administrator email address you entered is invalid.'; + + if ($title == '') + $alerts[] = 'You must enter a board title.'; + + $default_lang = preg_replace('#[\.\\\/]#', '', $default_lang); + if (!file_exists(PUN_ROOT.'lang/'.$default_lang.'/common.php')) + $alerts[] = 'The default language chosen doesn\'t seem to exist.'; + + $default_style = preg_replace('#[\.\\\/]#', '', $default_style); + if (!file_exists(PUN_ROOT.'style/'.$default_style.'.css')) + $alerts[] = 'The default style chosen doesn\'t seem to exist.'; +} + +if (!isset($_POST['form_sent']) || !empty($alerts)) +{ + // Determine available database extensions + $dual_mysql = false; + $db_extensions = array(); + $mysql_innodb = false; + if (function_exists('mysqli_connect')) + { + $db_extensions[] = array('mysqli', 'MySQL Improved'); + $db_extensions[] = array('mysqli_innodb', 'MySQL Improved (InnoDB)'); + $mysql_innodb = true; + } + if (function_exists('mysql_connect')) + { + $db_extensions[] = array('mysql', 'MySQL Standard'); + $db_extensions[] = array('mysql_innodb', 'MySQL Standard (InnoDB)'); + $mysql_innodb = true; + + if (count($db_extensions) > 2) + $dual_mysql = true; + } + if (function_exists('sqlite_open')) + $db_extensions[] = array('sqlite', 'SQLite'); + if (function_exists('pg_connect')) + $db_extensions[] = array('pgsql', 'PostgreSQL'); + + if (empty($db_extensions)) + exit('This PHP environment does not have support for any of the databases that FluxBB supports. PHP needs to have support for either MySQL, PostgreSQL or SQLite in order for FluxBB to be installed.'); + +?> + + + + + +FluxBB Installation + + + + + +
    +
    +
    + +
    +
    +
    +

    FluxBB Installation

    +

    Welcome to FluxBB installation. You are about to install FluxBB. In order to install FluxBB, you must complete the form set out below. If you encounter any difficulties with the installation, please refer to the documentation.

    +
    +
    +
    + +
    +
    +

    Install FluxBB 1.4

    +
    +
    +
    +
    +
    +

    The following errors need to be corrected:

    +
      +'.$cur_alert.''."\n"; +?> +
    +
    +
    +
    +
    +

    Database setup

    +

    Please enter the requested information in order to setup your database for FluxBB. You must know all the information asked for before proceeding with the installation.

    +
    +
    + Select your database type +
    +

    FluxBB currently supports MySQL, PostgreSQL and SQLite. If your database of choice is missing from the drop-down menu below, it means this PHP environment does not have support for that particular database. More information regarding support for particular versions of each database can be found in the FAQ.

    +

    FluxBB has detected that your PHP environment supports two different ways of communicating with MySQL. The two options are called standard and improved. If you are uncertain which one to use, start by trying improved and if that fails, try standard.

    +

    FluxBB has detected that your MySQL server might support InnoDB. This would be a good choice if you are planning to run a large forum. If you are uncertain, it is recommended that you do not use InnoDB.

    + +
    +
    +
    +
    +
    + Enter your database server hostname +
    +

    The address of the database server (example: localhost, db.myhost.com or 192.168.0.15). You can specify a custom port number if your database doesn't run on the default port (example: localhost:3580). For SQLite support, just enter anything or leave it at 'localhost'.

    + +
    +
    +
    +
    +
    + Enter the name of your database +
    +

    The name of the database that FluxBB will be installed into. The database must exist. For SQLite, this is the relative path to the database file. If the SQLite database file does not exist, FluxBB will attempt to create it.

    + +
    +
    +
    +
    +
    + Enter your database username and password +
    +

    Enter the username and password with which you connect to the database. Ignore for SQLite.

    + + +
    +
    +
    +
    +
    +
    + Enter database table prefix +
    +

    If you like, you can specify a table prefix. This way you can run multiple copies of FluxBB in the same database (example: foo_).

    + +
    +
    +
    +
    +
    +

    Administration setup

    +

    Please enter the requested information in order to setup an administrator for your FluxBB installation.

    +
    +
    + Enter Administrator's username +
    +

    The username of the forum administrator. You can later create more administrators and moderators. Usernames can be between 2 and 25 characters long.

    + +
    +
    +
    +
    +
    + Enter and confirm Administrator's password +
    +

    Passwords must be at least 4 characters long. Passwords are case sensitive.

    + + +
    +
    +
    +
    +
    +
    + Enter Administrator's email +
    +

    The email address of the forum administrator.

    + +
    +
    +
    +
    +
    +

    Board setup

    +

    Please enter the requested information in order to setup your FluxBB board.

    +
    +
    + Enter your board's title +
    +

    The title of this bulletin board (shown at the top of every page).

    + +
    +
    +
    +
    +
    + Enter your board's description +
    +

    A short description of this bulletin board (shown at the top of every page). This field may contain HTML.

    + +
    +
    +
    +
    +
    + Enter the Base URL of your FluxBB installation +
    +

    The URL (without trailing slash) of your FluxBB forum (example: http://forum.myhost.com or http://myhost.com/~myuser). This must be correct, otherwise, administrators and moderators will not be able to submit any forms. Please note that the preset value below is just an educated guess by FluxBB.

    + +
    +
    +
    +
    +
    + Choose the default language +
    +

    The default language used for guests and users who haven't changed from the default in their profile.

    + +
    +
    +
    +
    +
    + Choose the default style +
    +

    The default style used for guests and users who haven't changed from the default in their profile.

    + +
    +
    +
    +

    +
    +
    +
    +
    + +
    +
    +
    + + + + 0 && (!preg_match('/^[a-zA-Z_][a-zA-Z0-9_]*$/', $db_prefix) || strlen($db_prefix) > 40)) + error('The table prefix \''.$db->prefix.'\' contains illegal characters or is too long. The prefix may contain the letters a to z, any numbers and the underscore character. They must however not start with a number. The maximum length is 40 characters. Please choose a different prefix'); + + // Do some DB type specific checks + switch ($db_type) + { + case 'mysql': + case 'mysqli': + case 'mysql_innodb': + case 'mysqli_innodb': + $mysql_info = $db->get_version(); + if (version_compare($mysql_info['version'], MIN_MYSQL_VERSION, '<')) + error('You are running MySQL version '.$mysql_version.'. FluxBB '.FORUM_VERSION.' requires at least MySQL '.MIN_MYSQL_VERSION.' to run properly. You must upgrade your MySQL installation before you can continue'); + break; + + case 'pgsql': + $pgsql_info = $db->get_version(); + if (version_compare($pgsql_info['version'], MIN_PGSQL_VERSION, '<')) + error('You are running PostgreSQL version '.$pgsql_info.'. FluxBB '.FORUM_VERSION.' requires at least PostgreSQL '.MIN_PGSQL_VERSION.' to run properly. You must upgrade your PostgreSQL installation before you can continue'); + break; + + case 'sqlite': + if (strtolower($db_prefix) == 'sqlite_') + error('The table prefix \'sqlite_\' is reserved for use by the SQLite engine. Please choose a different prefix'); + break; + } + + + // Make sure FluxBB isn't already installed + $result = $db->query('SELECT 1 FROM '.$db_prefix.'users WHERE id=1'); + if ($db->num_rows($result)) + error('A table called "'.$db_prefix.'users" is already present in the database "'.$db_name.'". This could mean that FluxBB is already installed or that another piece of software is installed and is occupying one or more of the table names FluxBB requires. If you want to install multiple copies of FluxBB in the same database, you must choose a different table prefix'); + + // Check if InnoDB is available + if ($db_type == 'mysql_innodb' || $db_type == 'mysqli_innodb') + { + $result = $db->query('SHOW VARIABLES LIKE \'have_innodb\''); + list (, $result) = $db->fetch_row($result); + if ((strtoupper($result) != 'YES')) + error('InnoDB does not seem to be enabled. Please choose a database layer that does not have InnoDB support, or enable InnoDB on your MySQL server'); + } + + + // Start a transaction + $db->start_transaction(); + + + // Create all tables + $schema = array( + 'FIELDS' => array( + 'id' => array( + 'datatype' => 'SERIAL', + 'allow_null' => false + ), + 'username' => array( + 'datatype' => 'VARCHAR(200)', + 'allow_null' => true + ), + 'ip' => array( + 'datatype' => 'VARCHAR(255)', + 'allow_null' => true + ), + 'email' => array( + 'datatype' => 'VARCHAR(80)', + 'allow_null' => true + ), + 'message' => array( + 'datatype' => 'VARCHAR(255)', + 'allow_null' => true + ), + 'expire' => array( + 'datatype' => 'INT(10) UNSIGNED', + 'allow_null' => true + ), + 'ban_creator' => array( + 'datatype' => 'INT(10) UNSIGNED', + 'allow_null' => false, + 'default' => '0' + ) + ), + 'PRIMARY KEY' => array('id'), + 'INDEXES' => array( + 'username_idx' => array('username') + ) + ); + + if ($db_type == 'mysql' || $db_type == 'mysqli' || $db_type == 'mysql_innodb' || $db_type == 'mysqli_innodb') + $schema['INDEXES']['username_idx'] = array('username(25)'); + + $db->create_table('bans', $schema) or error('Unable to create bans table', __FILE__, __LINE__, $db->error()); + + + $schema = array( + 'FIELDS' => array( + 'id' => array( + 'datatype' => 'SERIAL', + 'allow_null' => false + ), + 'cat_name' => array( + 'datatype' => 'VARCHAR(80)', + 'allow_null' => false, + 'default' => '\'New Category\'' + ), + 'disp_position' => array( + 'datatype' => 'INT(10)', + 'allow_null' => false, + 'default' => '0' + ) + ), + 'PRIMARY KEY' => array('id') + ); + + $db->create_table('categories', $schema) or error('Unable to create categories table', __FILE__, __LINE__, $db->error()); + + + $schema = array( + 'FIELDS' => array( + 'id' => array( + 'datatype' => 'SERIAL', + 'allow_null' => false + ), + 'search_for' => array( + 'datatype' => 'VARCHAR(60)', + 'allow_null' => false, + 'default' => '\'\'' + ), + 'replace_with' => array( + 'datatype' => 'VARCHAR(60)', + 'allow_null' => false, + 'default' => '\'\'' + ) + ), + 'PRIMARY KEY' => array('id') + ); + + $db->create_table('censoring', $schema) or error('Unable to create censoring table', __FILE__, __LINE__, $db->error()); + + + $schema = array( + 'FIELDS' => array( + 'conf_name' => array( + 'datatype' => 'VARCHAR(255)', + 'allow_null' => false, + 'default' => '\'\'' + ), + 'conf_value' => array( + 'datatype' => 'TEXT', + 'allow_null' => true + ) + ), + 'PRIMARY KEY' => array('conf_name') + ); + + $db->create_table('config', $schema) or error('Unable to create config table', __FILE__, __LINE__, $db->error()); + + + $schema = array( + 'FIELDS' => array( + 'group_id' => array( + 'datatype' => 'INT(10)', + 'allow_null' => false, + 'default' => '0' + ), + 'forum_id' => array( + 'datatype' => 'INT(10)', + 'allow_null' => false, + 'default' => '0' + ), + 'read_forum' => array( + 'datatype' => 'TINYINT(1)', + 'allow_null' => false, + 'default' => '1' + ), + 'post_replies' => array( + 'datatype' => 'TINYINT(1)', + 'allow_null' => false, + 'default' => '1' + ), + 'post_topics' => array( + 'datatype' => 'TINYINT(1)', + 'allow_null' => false, + 'default' => '1' + ) + ), + 'PRIMARY KEY' => array('group_id', 'forum_id') + ); + + $db->create_table('forum_perms', $schema) or error('Unable to create forum_perms table', __FILE__, __LINE__, $db->error()); + + + $schema = array( + 'FIELDS' => array( + 'id' => array( + 'datatype' => 'SERIAL', + 'allow_null' => false + ), + 'forum_name' => array( + 'datatype' => 'VARCHAR(80)', + 'allow_null' => false, + 'default' => '\'New forum\'' + ), + 'forum_desc' => array( + 'datatype' => 'TEXT', + 'allow_null' => true + ), + 'redirect_url' => array( + 'datatype' => 'VARCHAR(100)', + 'allow_null' => true + ), + 'moderators' => array( + 'datatype' => 'TEXT', + 'allow_null' => true + ), + 'num_topics' => array( + 'datatype' => 'MEDIUMINT(8) UNSIGNED', + 'allow_null' => false, + 'default' => '0' + ), + 'num_posts' => array( + 'datatype' => 'MEDIUMINT(8) UNSIGNED', + 'allow_null' => false, + 'default' => '0' + ), + 'last_post' => array( + 'datatype' => 'INT(10) UNSIGNED', + 'allow_null' => true + ), + 'last_post_id' => array( + 'datatype' => 'INT(10) UNSIGNED', + 'allow_null' => true + ), + 'last_poster' => array( + 'datatype' => 'VARCHAR(200)', + 'allow_null' => true + ), + 'sort_by' => array( + 'datatype' => 'TINYINT(1)', + 'allow_null' => false, + 'default' => '0' + ), + 'disp_position' => array( + 'datatype' => 'INT(10)', + 'allow_null' => false, + 'default' => '0' + ), + 'cat_id' => array( + 'datatype' => 'INT(10) UNSIGNED', + 'allow_null' => false, + 'default' => '0' + ) + ), + 'PRIMARY KEY' => array('id') + ); + + $db->create_table('forums', $schema) or error('Unable to create forums table', __FILE__, __LINE__, $db->error()); + + + $schema = array( + 'FIELDS' => array( + 'g_id' => array( + 'datatype' => 'SERIAL', + 'allow_null' => false + ), + 'g_title' => array( + 'datatype' => 'VARCHAR(50)', + 'allow_null' => false, + 'default' => '\'\'' + ), + 'g_user_title' => array( + 'datatype' => 'VARCHAR(50)', + 'allow_null' => true + ), + 'g_moderator' => array( + 'datatype' => 'TINYINT(1)', + 'allow_null' => false, + 'default' => '0' + ), + 'g_mod_edit_users' => array( + 'datatype' => 'TINYINT(1)', + 'allow_null' => false, + 'default' => '0' + ), + 'g_mod_rename_users' => array( + 'datatype' => 'TINYINT(1)', + 'allow_null' => false, + 'default' => '0' + ), + 'g_mod_change_passwords' => array( + 'datatype' => 'TINYINT(1)', + 'allow_null' => false, + 'default' => '0' + ), + 'g_mod_ban_users' => array( + 'datatype' => 'TINYINT(1)', + 'allow_null' => false, + 'default' => '0' + ), + 'g_read_board' => array( + 'datatype' => 'TINYINT(1)', + 'allow_null' => false, + 'default' => '1' + ), + 'g_view_users' => array( + 'datatype' => 'TINYINT(1)', + 'allow_null' => false, + 'default' => '1' + ), + 'g_post_replies' => array( + 'datatype' => 'TINYINT(1)', + 'allow_null' => false, + 'default' => '1' + ), + 'g_post_topics' => array( + 'datatype' => 'TINYINT(1)', + 'allow_null' => false, + 'default' => '1' + ), + 'g_edit_posts' => array( + 'datatype' => 'TINYINT(1)', + 'allow_null' => false, + 'default' => '1' + ), + 'g_delete_posts' => array( + 'datatype' => 'TINYINT(1)', + 'allow_null' => false, + 'default' => '1' + ), + 'g_delete_topics' => array( + 'datatype' => 'TINYINT(1)', + 'allow_null' => false, + 'default' => '1' + ), + 'g_set_title' => array( + 'datatype' => 'TINYINT(1)', + 'allow_null' => false, + 'default' => '1' + ), + 'g_search' => array( + 'datatype' => 'TINYINT(1)', + 'allow_null' => false, + 'default' => '1' + ), + 'g_search_users' => array( + 'datatype' => 'TINYINT(1)', + 'allow_null' => false, + 'default' => '1' + ), + 'g_send_email' => array( + 'datatype' => 'TINYINT(1)', + 'allow_null' => false, + 'default' => '1' + ), + 'g_post_flood' => array( + 'datatype' => 'SMALLINT(6)', + 'allow_null' => false, + 'default' => '30' + ), + 'g_search_flood' => array( + 'datatype' => 'SMALLINT(6)', + 'allow_null' => false, + 'default' => '30' + ), + 'g_email_flood' => array( + 'datatype' => 'SMALLINT(6)', + 'allow_null' => false, + 'default' => '60' + ) + ), + 'PRIMARY KEY' => array('g_id') + ); + + $db->create_table('groups', $schema) or error('Unable to create groups table', __FILE__, __LINE__, $db->error()); + + + $schema = array( + 'FIELDS' => array( + 'user_id' => array( + 'datatype' => 'INT(10) UNSIGNED', + 'allow_null' => false, + 'default' => '1' + ), + 'ident' => array( + 'datatype' => 'VARCHAR(200)', + 'allow_null' => false, + 'default' => '\'\'' + ), + 'logged' => array( + 'datatype' => 'INT(10) UNSIGNED', + 'allow_null' => false, + 'default' => '0' + ), + 'idle' => array( + 'datatype' => 'TINYINT(1)', + 'allow_null' => false, + 'default' => '0' + ), + 'last_post' => array( + 'datatype' => 'INT(10) UNSIGNED', + 'allow_null' => true + ), + 'last_search' => array( + 'datatype' => 'INT(10) UNSIGNED', + 'allow_null' => true + ), + ), + 'UNIQUE KEYS' => array( + 'user_id_ident_idx' => array('user_id', 'ident') + ), + 'INDEXES' => array( + 'ident_idx' => array('ident'), + 'logged_idx' => array('logged') + ), + 'ENGINE' => 'HEAP' + ); + + if ($db_type == 'mysql' || $db_type == 'mysqli' || $db_type == 'mysql_innodb' || $db_type == 'mysqli_innodb') + { + $schema['UNIQUE KEYS']['user_id_ident_idx'] = array('user_id', 'ident(25)'); + $schema['INDEXES']['ident_idx'] = array('ident(25)'); + } + + if ($db_type == 'mysql_innodb' || $db_type == 'mysqli_innodb') + $schema['ENGINE'] = 'InnoDB'; + + $db->create_table('online', $schema) or error('Unable to create online table', __FILE__, __LINE__, $db->error()); + + + $schema = array( + 'FIELDS' => array( + 'id' => array( + 'datatype' => 'SERIAL', + 'allow_null' => false + ), + 'poster' => array( + 'datatype' => 'VARCHAR(200)', + 'allow_null' => false, + 'default' => '\'\'' + ), + 'poster_id' => array( + 'datatype' => 'INT(10) UNSIGNED', + 'allow_null' => false, + 'default' => '1' + ), + 'poster_ip' => array( + 'datatype' => 'VARCHAR(39)', + 'allow_null' => true + ), + 'poster_email' => array( + 'datatype' => 'VARCHAR(80)', + 'allow_null' => true + ), + 'message' => array( + 'datatype' => 'TEXT', + 'allow_null' => true + ), + 'hide_smilies' => array( + 'datatype' => 'TINYINT(1)', + 'allow_null' => false, + 'default' => '0' + ), + 'posted' => array( + 'datatype' => 'INT(10) UNSIGNED', + 'allow_null' => false, + 'default' => '0' + ), + 'edited' => array( + 'datatype' => 'INT(10) UNSIGNED', + 'allow_null' => true + ), + 'edited_by' => array( + 'datatype' => 'VARCHAR(200)', + 'allow_null' => true + ), + 'topic_id' => array( + 'datatype' => 'INT(10) UNSIGNED', + 'allow_null' => false, + 'default' => '0' + ) + ), + 'PRIMARY KEY' => array('id'), + 'INDEXES' => array( + 'topic_id_idx' => array('topic_id'), + 'multi_idx' => array('poster_id', 'topic_id') + ) + ); + + $db->create_table('posts', $schema) or error('Unable to create posts table', __FILE__, __LINE__, $db->error()); + + + $schema = array( + 'FIELDS' => array( + 'id' => array( + 'datatype' => 'SERIAL', + 'allow_null' => false + ), + 'rank' => array( + 'datatype' => 'VARCHAR(50)', + 'allow_null' => false, + 'default' => '\'\'' + ), + 'min_posts' => array( + 'datatype' => 'MEDIUMINT(8) UNSIGNED', + 'allow_null' => false, + 'default' => '0' + ) + ), + 'PRIMARY KEY' => array('id') + ); + + $db->create_table('ranks', $schema) or error('Unable to create ranks table', __FILE__, __LINE__, $db->error()); + + + $schema = array( + 'FIELDS' => array( + 'id' => array( + 'datatype' => 'SERIAL', + 'allow_null' => false + ), + 'post_id' => array( + 'datatype' => 'INT(10) UNSIGNED', + 'allow_null' => false, + 'default' => '0' + ), + 'topic_id' => array( + 'datatype' => 'INT(10) UNSIGNED', + 'allow_null' => false, + 'default' => '0' + ), + 'forum_id' => array( + 'datatype' => 'INT(10) UNSIGNED', + 'allow_null' => false, + 'default' => '0' + ), + 'reported_by' => array( + 'datatype' => 'INT(10) UNSIGNED', + 'allow_null' => false, + 'default' => '0' + ), + 'created' => array( + 'datatype' => 'INT(10) UNSIGNED', + 'allow_null' => false, + 'default' => '0' + ), + 'message' => array( + 'datatype' => 'TEXT', + 'allow_null' => true + ), + 'zapped' => array( + 'datatype' => 'INT(10) UNSIGNED', + 'allow_null' => true + ), + 'zapped_by' => array( + 'datatype' => 'INT(10) UNSIGNED', + 'allow_null' => true + ) + ), + 'PRIMARY KEY' => array('id'), + 'INDEXES' => array( + 'zapped_idx' => array('zapped') + ) + ); + + $db->create_table('reports', $schema) or error('Unable to create reports table', __FILE__, __LINE__, $db->error()); + + + $schema = array( + 'FIELDS' => array( + 'id' => array( + 'datatype' => 'INT(10) UNSIGNED', + 'allow_null' => false, + 'default' => '0' + ), + 'ident' => array( + 'datatype' => 'VARCHAR(200)', + 'allow_null' => false, + 'default' => '\'\'' + ), + 'search_data' => array( + 'datatype' => 'MEDIUMTEXT', + 'allow_null' => true + ) + ), + 'PRIMARY KEY' => array('id'), + 'INDEXES' => array( + 'ident_idx' => array('ident') + ) + ); + + if ($db_type == 'mysql' || $db_type == 'mysqli' || $db_type == 'mysql_innodb' || $db_type == 'mysqli_innodb') + $schema['INDEXES']['ident_idx'] = array('ident(8)'); + + $db->create_table('search_cache', $schema) or error('Unable to create search_cache table', __FILE__, __LINE__, $db->error()); + + + $schema = array( + 'FIELDS' => array( + 'post_id' => array( + 'datatype' => 'INT(10) UNSIGNED', + 'allow_null' => false, + 'default' => '0' + ), + 'word_id' => array( + 'datatype' => 'INT(10) UNSIGNED', + 'allow_null' => false, + 'default' => '0' + ), + 'subject_match' => array( + 'datatype' => 'TINYINT(1)', + 'allow_null' => false, + 'default' => '0' + ) + ), + 'INDEXES' => array( + 'word_id_idx' => array('word_id'), + 'post_id_idx' => array('post_id') + ) + ); + + $db->create_table('search_matches', $schema) or error('Unable to create search_matches table', __FILE__, __LINE__, $db->error()); + + + $schema = array( + 'FIELDS' => array( + 'id' => array( + 'datatype' => 'SERIAL', + 'allow_null' => false + ), + 'word' => array( + 'datatype' => 'VARCHAR(20)', + 'allow_null' => false, + 'default' => '\'\'', + 'collation' => 'bin' + ) + ), + 'PRIMARY KEY' => array('word'), + 'INDEXES' => array( + 'id_idx' => array('id') + ) + ); + + if ($db_type == 'sqlite') + { + $schema['PRIMARY KEY'] = array('id'); + $schema['UNIQUE KEYS'] = array('word_idx' => array('word')); + } + + $db->create_table('search_words', $schema) or error('Unable to create search_words table', __FILE__, __LINE__, $db->error()); + + + $schema = array( + 'FIELDS' => array( + 'user_id' => array( + 'datatype' => 'INT(10) UNSIGNED', + 'allow_null' => false, + 'default' => '0' + ), + 'topic_id' => array( + 'datatype' => 'INT(10) UNSIGNED', + 'allow_null' => false, + 'default' => '0' + ) + ), + 'PRIMARY KEY' => array('user_id', 'topic_id') + ); + + $db->create_table('subscriptions', $schema) or error('Unable to create subscriptions table', __FILE__, __LINE__, $db->error()); + + + $schema = array( + 'FIELDS' => array( + 'id' => array( + 'datatype' => 'SERIAL', + 'allow_null' => false + ), + 'poster' => array( + 'datatype' => 'VARCHAR(200)', + 'allow_null' => false, + 'default' => '\'\'' + ), + 'subject' => array( + 'datatype' => 'VARCHAR(255)', + 'allow_null' => false, + 'default' => '\'\'' + ), + 'posted' => array( + 'datatype' => 'INT(10) UNSIGNED', + 'allow_null' => false, + 'default' => '0' + ), + 'first_post_id' => array( + 'datatype' => 'INT(10) UNSIGNED', + 'allow_null' => false, + 'default' => '0' + ), + 'last_post' => array( + 'datatype' => 'INT(10) UNSIGNED', + 'allow_null' => false, + 'default' => '0' + ), + 'last_post_id' => array( + 'datatype' => 'INT(10) UNSIGNED', + 'allow_null' => false, + 'default' => '0' + ), + 'last_poster' => array( + 'datatype' => 'VARCHAR(200)', + 'allow_null' => true + ), + 'num_views' => array( + 'datatype' => 'MEDIUMINT(8) UNSIGNED', + 'allow_null' => false, + 'default' => '0' + ), + 'num_replies' => array( + 'datatype' => 'MEDIUMINT(8) UNSIGNED', + 'allow_null' => false, + 'default' => '0' + ), + 'closed' => array( + 'datatype' => 'TINYINT(1)', + 'allow_null' => false, + 'default' => '0' + ), + 'sticky' => array( + 'datatype' => 'TINYINT(1)', + 'allow_null' => false, + 'default' => '0' + ), + 'moved_to' => array( + 'datatype' => 'INT(10) UNSIGNED', + 'allow_null' => true + ), + 'forum_id' => array( + 'datatype' => 'INT(10) UNSIGNED', + 'allow_null' => false, + 'default' => '0' + ) + ), + 'PRIMARY KEY' => array('id'), + 'INDEXES' => array( + 'forum_id_idx' => array('forum_id'), + 'moved_to_idx' => array('moved_to'), + 'last_post_idx' => array('last_post'), + 'first_post_id_idx' => array('first_post_id') + ) + ); + + $db->create_table('topics', $schema) or error('Unable to create topics table', __FILE__, __LINE__, $db->error()); + + + $schema = array( + 'FIELDS' => array( + 'id' => array( + 'datatype' => 'SERIAL', + 'allow_null' => false + ), + 'group_id' => array( + 'datatype' => 'INT(10) UNSIGNED', + 'allow_null' => false, + 'default' => '3' + ), + 'username' => array( + 'datatype' => 'VARCHAR(200)', + 'allow_null' => false, + 'default' => '\'\'' + ), + 'password' => array( + 'datatype' => 'VARCHAR(40)', + 'allow_null' => false, + 'default' => '\'\'' + ), + 'email' => array( + 'datatype' => 'VARCHAR(80)', + 'allow_null' => false, + 'default' => '\'\'' + ), + 'title' => array( + 'datatype' => 'VARCHAR(50)', + 'allow_null' => true + ), + 'realname' => array( + 'datatype' => 'VARCHAR(40)', + 'allow_null' => true + ), + 'url' => array( + 'datatype' => 'VARCHAR(100)', + 'allow_null' => true + ), + 'jabber' => array( + 'datatype' => 'VARCHAR(80)', + 'allow_null' => true + ), + 'icq' => array( + 'datatype' => 'VARCHAR(12)', + 'allow_null' => true + ), + 'msn' => array( + 'datatype' => 'VARCHAR(80)', + 'allow_null' => true + ), + 'aim' => array( + 'datatype' => 'VARCHAR(30)', + 'allow_null' => true + ), + 'yahoo' => array( + 'datatype' => 'VARCHAR(30)', + 'allow_null' => true + ), + 'location' => array( + 'datatype' => 'VARCHAR(30)', + 'allow_null' => true + ), + 'signature' => array( + 'datatype' => 'TEXT', + 'allow_null' => true + ), + 'disp_topics' => array( + 'datatype' => 'TINYINT(3) UNSIGNED', + 'allow_null' => true + ), + 'disp_posts' => array( + 'datatype' => 'TINYINT(3) UNSIGNED', + 'allow_null' => true + ), + 'email_setting' => array( + 'datatype' => 'TINYINT(1)', + 'allow_null' => false, + 'default' => '1' + ), + 'notify_with_post' => array( + 'datatype' => 'TINYINT(1)', + 'allow_null' => false, + 'default' => '0' + ), + 'auto_notify' => array( + 'datatype' => 'TINYINT(1)', + 'allow_null' => false, + 'default' => '0' + ), + 'show_smilies' => array( + 'datatype' => 'TINYINT(1)', + 'allow_null' => false, + 'default' => '1' + ), + 'show_img' => array( + 'datatype' => 'TINYINT(1)', + 'allow_null' => false, + 'default' => '1' + ), + 'show_img_sig' => array( + 'datatype' => 'TINYINT(1)', + 'allow_null' => false, + 'default' => '1' + ), + 'show_avatars' => array( + 'datatype' => 'TINYINT(1)', + 'allow_null' => false, + 'default' => '1' + ), + 'show_sig' => array( + 'datatype' => 'TINYINT(1)', + 'allow_null' => false, + 'default' => '1' + ), + 'timezone' => array( + 'datatype' => 'FLOAT', + 'allow_null' => false, + 'default' => '0' + ), + 'dst' => array( + 'datatype' => 'TINYINT(1)', + 'allow_null' => false, + 'default' => '0' + ), + 'time_format' => array( + 'datatype' => 'TINYINT(1)', + 'allow_null' => false, + 'default' => '0' + ), + 'date_format' => array( + 'datatype' => 'TINYINT(1)', + 'allow_null' => false, + 'default' => '0' + ), + 'language' => array( + 'datatype' => 'VARCHAR(25)', + 'allow_null' => false, + 'default' => '\'English\'' + ), + 'style' => array( + 'datatype' => 'VARCHAR(25)', + 'allow_null' => false, + 'default' => '\''.$db->escape($default_style).'\'' + ), + 'num_posts' => array( + 'datatype' => 'INT(10) UNSIGNED', + 'allow_null' => false, + 'default' => '0' + ), + 'last_post' => array( + 'datatype' => 'INT(10) UNSIGNED', + 'allow_null' => true + ), + 'last_search' => array( + 'datatype' => 'INT(10) UNSIGNED', + 'allow_null' => true + ), + 'last_email_sent' => array( + 'datatype' => 'INT(10) UNSIGNED', + 'allow_null' => true + ), + 'registered' => array( + 'datatype' => 'INT(10) UNSIGNED', + 'allow_null' => false, + 'default' => '0' + ), + 'registration_ip' => array( + 'datatype' => 'VARCHAR(39)', + 'allow_null' => false, + 'default' => '\'0.0.0.0\'' + ), + 'last_visit' => array( + 'datatype' => 'INT(10) UNSIGNED', + 'allow_null' => false, + 'default' => '0' + ), + 'admin_note' => array( + 'datatype' => 'VARCHAR(30)', + 'allow_null' => true + ), + 'activate_string' => array( + 'datatype' => 'VARCHAR(80)', + 'allow_null' => true + ), + 'activate_key' => array( + 'datatype' => 'VARCHAR(8)', + 'allow_null' => true + ), + ), + 'PRIMARY KEY' => array('id'), + 'UNIQUE KEYS' => array( + 'username_idx' => array('username') + ), + 'INDEXES' => array( + 'registered_idx' => array('registered') + ) + ); + + if ($db_type == 'mysql' || $db_type == 'mysqli' || $db_type == 'mysql_innodb' || $db_type == 'mysqli_innodb') + $schema['UNIQUE KEYS']['username_idx'] = array('username(25)'); + + $db->create_table('users', $schema) or error('Unable to create users table', __FILE__, __LINE__, $db->error()); + + + $now = time(); + + // Insert the four preset groups + $db->query('INSERT INTO '.$db->prefix.'groups ('.($db_type != 'pgsql' ? 'g_id, ' : '').'g_title, g_user_title, g_moderator, g_mod_edit_users, g_mod_rename_users, g_mod_change_passwords, g_mod_ban_users, g_read_board, g_view_users, g_post_replies, g_post_topics, g_edit_posts, g_delete_posts, g_delete_topics, g_set_title, g_search, g_search_users, g_send_email, g_post_flood, g_search_flood, g_email_flood) VALUES('.($db_type != 'pgsql' ? '1, ' : '')."'Administrators', 'Administrator', 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0)") or error('Unable to add group', __FILE__, __LINE__, $db->error()); + + $db->query('INSERT INTO '.$db->prefix.'groups ('.($db_type != 'pgsql' ? 'g_id, ' : '').'g_title, g_user_title, g_moderator, g_mod_edit_users, g_mod_rename_users, g_mod_change_passwords, g_mod_ban_users, g_read_board, g_view_users, g_post_replies, g_post_topics, g_edit_posts, g_delete_posts, g_delete_topics, g_set_title, g_search, g_search_users, g_send_email, g_post_flood, g_search_flood, g_email_flood) VALUES('.($db_type != 'pgsql' ? '2, ' : '')."'Moderators', 'Moderator', 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0)") or error('Unable to add group', __FILE__, __LINE__, $db->error()); + + $db->query('INSERT INTO '.$db->prefix.'groups ('.($db_type != 'pgsql' ? 'g_id, ' : '').'g_title, g_user_title, g_moderator, g_mod_edit_users, g_mod_rename_users, g_mod_change_passwords, g_mod_ban_users, g_read_board, g_view_users, g_post_replies, g_post_topics, g_edit_posts, g_delete_posts, g_delete_topics, g_set_title, g_search, g_search_users, g_send_email, g_post_flood, g_search_flood, g_email_flood) VALUES('.($db_type != 'pgsql' ? '3, ' : '')."'Guest', NULL, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 60, 30, 0)") or error('Unable to add group', __FILE__, __LINE__, $db->error()); + + $db->query('INSERT INTO '.$db->prefix.'groups ('.($db_type != 'pgsql' ? 'g_id, ' : '').'g_title, g_user_title, g_moderator, g_mod_edit_users, g_mod_rename_users, g_mod_change_passwords, g_mod_ban_users, g_read_board, g_view_users, g_post_replies, g_post_topics, g_edit_posts, g_delete_posts, g_delete_topics, g_set_title, g_search, g_search_users, g_send_email, g_post_flood, g_search_flood, g_email_flood) VALUES('.($db_type != 'pgsql' ? '4, ' : '')."'Members', NULL, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 60, 30, 60)") or error('Unable to add group', __FILE__, __LINE__, $db->error()); + + // Insert guest and first admin user + $db->query('INSERT INTO '.$db_prefix."users (group_id, username, password, email) VALUES(3, 'Guest', 'Guest', 'Guest')") + or error('Unable to add guest user. Please check your configuration and try again', __FILE__, __LINE__, $db->error()); + + $db->query('INSERT INTO '.$db_prefix."users (group_id, username, password, email, num_posts, last_post, registered, registration_ip, last_visit) VALUES(1, '".$db->escape($username)."', '".pun_hash($password1)."', '$email', 1, ".$now.", ".$now.", '127.0.0.1', ".$now.')') + or error('Unable to add administrator user. Please check your configuration and try again', __FILE__, __LINE__, $db->error()); + + // Enable/disable avatars depending on file_uploads setting in PHP configuration + $avatars = in_array(strtolower(@ini_get('file_uploads')), array('on', 'true', '1')) ? 1 : 0; + + // Insert config data + $config = array( + 'o_cur_version' => "'".FORUM_VERSION."'", + 'o_database_revision' => "'".FORUM_DB_REVISION."'", + 'o_searchindex_revision' => "'".FORUM_SI_REVISION."'", + 'o_parser_revision' => "'".FORUM_PARSER_REVISION."'", + 'o_board_title' => "'".$db->escape($title)."'", + 'o_board_desc' => "'".$db->escape($description)."'", + 'o_default_timezone' => "'0'", + 'o_time_format' => "'H:i:s'", + 'o_date_format' => "'Y-m-d'", + 'o_timeout_visit' => "'1800'", + 'o_timeout_online' => "'300'", + 'o_redirect_delay' => "'1'", + 'o_show_version' => "'0'", + 'o_show_user_info' => "'1'", + 'o_show_post_count' => "'1'", + 'o_signatures' => "'1'", + 'o_smilies' => "'1'", + 'o_smilies_sig' => "'1'", + 'o_make_links' => "'1'", + 'o_default_lang' => "'".$db->escape($default_lang)."'", + 'o_default_style' => "'".$db->escape($default_style)."'", + 'o_default_user_group' => "'4'", + 'o_topic_review' => "'15'", + 'o_disp_topics_default' => "'30'", + 'o_disp_posts_default' => "'25'", + 'o_indent_num_spaces' => "'4'", + 'o_quote_depth' => "'3'", + 'o_quickpost' => "'1'", + 'o_users_online' => "'1'", + 'o_censoring' => "'0'", + 'o_ranks' => "'1'", + 'o_show_dot' => "'0'", + 'o_topic_views' => "'1'", + 'o_quickjump' => "'1'", + 'o_gzip' => "'0'", + 'o_additional_navlinks' => "''", + 'o_report_method' => "'0'", + 'o_regs_report' => "'0'", + 'o_default_email_setting' => "'1'", + 'o_mailing_list' => "'".$email."'", + 'o_avatars' => "'".$avatars."'", + 'o_avatars_dir' => "'img/avatars'", + 'o_avatars_width' => "'60'", + 'o_avatars_height' => "'60'", + 'o_avatars_size' => "'10240'", + 'o_search_all_forums' => "'1'", + 'o_base_url' => "'".$db->escape($base_url)."'", + 'o_admin_email' => "'".$email."'", + 'o_webmaster_email' => "'".$email."'", + 'o_subscriptions' => "'1'", + 'o_smtp_host' => "NULL", + 'o_smtp_user' => "NULL", + 'o_smtp_pass' => "NULL", + 'o_smtp_ssl' => "'0'", + 'o_regs_allow' => "'1'", + 'o_regs_verify' => "'0'", + 'o_announcement' => "'0'", + 'o_announcement_message' => "'Enter your announcement here.'", + 'o_rules' => "'0'", + 'o_rules_message' => "'Enter your rules here.'", + 'o_maintenance' => "'0'", + 'o_maintenance_message' => "'The forums are temporarily down for maintenance. Please try again in a few minutes.
    \\n
    \\n/Administrator'", + 'o_default_dst' => "'0'", + 'o_feed_type' => "'2'", + 'p_message_bbcode' => "'1'", + 'p_message_img_tag' => "'1'", + 'p_message_all_caps' => "'1'", + 'p_subject_all_caps' => "'1'", + 'p_sig_all_caps' => "'1'", + 'p_sig_bbcode' => "'1'", + 'p_sig_img_tag' => "'0'", + 'p_sig_length' => "'400'", + 'p_sig_lines' => "'4'", + 'p_allow_banned_email' => "'1'", + 'p_allow_dupe_email' => "'0'", + 'p_force_guest_email' => "'1'" + ); + + foreach ($config as $conf_name => $conf_value) + { + $db->query('INSERT INTO '.$db_prefix."config (conf_name, conf_value) VALUES('$conf_name', $conf_value)") + or error('Unable to insert into table '.$db_prefix.'config. Please check your configuration and try again', __FILE__, __LINE__, $db->error()); + } + + // Insert some other default data + $subject = 'Test post'; + $message = 'If you are looking at this (which I guess you are), the install of FluxBB appears to have worked! Now log in and head over to the administration control panel to configure your forum.'; + + $db->query('INSERT INTO '.$db_prefix."ranks (rank, min_posts) VALUES('New member', 0)") + or error('Unable to insert into table '.$db_prefix.'ranks. Please check your configuration and try again', __FILE__, __LINE__, $db->error()); + + $db->query('INSERT INTO '.$db_prefix."ranks (rank, min_posts) VALUES('Member', 10)") + or error('Unable to insert into table '.$db_prefix.'ranks. Please check your configuration and try again', __FILE__, __LINE__, $db->error()); + + $db->query('INSERT INTO '.$db_prefix."categories (cat_name, disp_position) VALUES('Test category', 1)") + or error('Unable to insert into table '.$db_prefix.'categories. Please check your configuration and try again', __FILE__, __LINE__, $db->error()); + + $db->query('INSERT INTO '.$db_prefix."forums (forum_name, forum_desc, num_topics, num_posts, last_post, last_post_id, last_poster, disp_position, cat_id) VALUES('Test forum', 'This is just a test forum', 1, 1, ".$now.", 1, '".$db->escape($username)."', 1, 1)") + or error('Unable to insert into table '.$db_prefix.'forums. Please check your configuration and try again', __FILE__, __LINE__, $db->error()); + + $db->query('INSERT INTO '.$db_prefix."topics (poster, subject, posted, first_post_id, last_post, last_post_id, last_poster, forum_id) VALUES('".$db->escape($username)."', '".$db->escape($subject)."', ".$now.", 1, ".$now.", 1, '".$db->escape($username)."', 1)") + or error('Unable to insert into table '.$db_prefix.'topics. Please check your configuration and try again', __FILE__, __LINE__, $db->error()); + + $db->query('INSERT INTO '.$db_prefix."posts (poster, poster_id, poster_ip, message, posted, topic_id) VALUES('".$db->escape($username)."', 2, '127.0.0.1', '".$db->escape($message)."', ".$now.', 1)') + or error('Unable to insert into table '.$db_prefix.'posts. Please check your configuration and try again', __FILE__, __LINE__, $db->error()); + + // Index the test post so searching for it works + require PUN_ROOT.'include/search_idx.php'; + $pun_config['o_default_lang'] = $default_lang; + update_search_index('post', 1, $message, $subject); + + $db->end_transaction(); + + + $alerts = array(); + // Check if the cache directory is writable + if (!@is_writable('./cache/')) + $alerts[] = 'The cache directory is currently not writable! In order for FluxBB to function properly, the directory named cache must be writable by PHP. Use chmod to set the appropriate directory permissions. If in doubt, chmod to 0777.'; + + // Check if default avatar directory is writable + if (!@is_writable('./img/avatars/')) + $alerts[] = 'The avatar directory is currently not writable! If you want users to be able to upload their own avatar images you must see to it that the directory named img/avatars is writable by PHP. You can later choose to save avatar images in a different directory (see Admin/Options). Use chmod to set the appropriate directory permissions. If in doubt, chmod to 0777.'; + + // Check if we disabled uploading avatars because file_uploads was disabled + if ($avatars == '0') + $alerts[] = 'File uploads appear to be disallowed on this server! If you want users to be able to upload their own avatar images you must enable the file_uploads configuration setting in PHP. Once file uploads have been enabled, avatar uploads can be enabled in Administration/Options/Features.'; + + // Add some random bytes at the end of the cookie name to prevent collisions + $cookie_name = 'pun_cookie_'.random_key(6, false, true); + + // Generate the config.php file data + $config = generate_config_file(); + + // Attempt to write config.php and serve it up for download if writing fails + $written = false; + if (is_writable(PUN_ROOT)) + { + $fh = @fopen(PUN_ROOT.'config.php', 'wb'); + if ($fh) + { + fwrite($fh, $config); + fclose($fh); + + $written = true; + } + } + + +?> + + + + + +FluxBB Installation + + + + +
    +
    +
    + +
    +
    +
    +

    FluxBB Installation

    +

    FluxBB has been installed. To finalize the installation please follow the instructions below.

    +
    +
    +
    + +
    + +
    +

    Final instructions

    +
    + +
    +
    +
    +

    To finalize the installation, you need to click on the button below to download a file called config.php. You then need to upload this file to the root directory of your FluxBB installation.

    +

    Once you have uploaded config.php, FluxBB will be fully installed! At that point, you may go to the forum index.

    +
    + + + + + + + + + + +
    +
      +'.$cur_alert.''."\n"; +?> +
    +
    +
    +

    +
    + + +
    +
    +
    +

    FluxBB has been fully installed! You may now go to the forum index.

    +
    +
    +
    + +
    +
    + +
    + +
    +
    +
    + + + + 'No user by that username registered. If you want to add a ban not tied to a specific username just leave the username blank.', +'No user ID message' => 'No user by that ID registered.', +'User is admin message' => 'The user %s is an administrator and can\'t be banned. If you want to ban an administrator, you must first demote him/her to moderator or user.', +'Must enter message' => 'You must enter either a username, an IP address or an email address (at least).', +'Cannot ban guest message' => 'The guest user cannot be banned.', +'Invalid IP message' => 'You entered an invalid IP/IP-range.', +'Invalid e-mail message' => 'The email address (e.g. user@domain.com) or partial email address domain (e.g. domain.com) you entered is invalid.', +'Invalid date message' => 'You entered an invalid expire date.', +'Invalid date reasons' => 'The format should be YYYY-MM-DD and the date must be at least one day in the future.', +'Ban added redirect' => 'Ban added. Redirecting …' , +'Ban edited redirect' => 'Ban edited. Redirecting …', +'Ban removed redirect' => 'Ban removed. Redirecting …', + +'New ban head' => 'New ban', +'Add ban subhead' => 'Add ban', +'Username label' => 'Username', +'Username help' => 'The username to ban (case-insensitive).', +'Username advanced help' => 'The username to ban (case-insensitive). The next page will let you enter a custom IP and email. If you just want to ban a specific IP/IP-range or email just leave it blank.', + +'Ban search head' => 'Ban search', +'Ban search subhead' => 'Enter search criteria', +'Ban search info' => 'Search for bans in the database. You can enter one or more terms to search for. Wildcards in the form of asterisks (*) are accepted.', +'Date help' => '(yyyy-mm-dd)', +'Message label' => 'Message', +'Expire after label' => 'Expire after', +'Expire before label' => 'Expire before', +'Order by label' => 'Order by', +'Order by username' => 'Username', +'Order by ip' => 'IP', +'Order by e-mail' => 'Email', +'Order by expire' => 'Expire date', +'Ascending' => 'Ascending', +'Descending' => 'Descending', +'Submit search' => 'Submit search', + +'E-mail label' => 'Email', +'E-mail help' => 'The email or email domain you wish to ban (e.g. someone@somewhere.com or somewhere.com). See "Allow banned email addresses" in Permissions for more info.', +'IP label' => 'IP address/IP-ranges', +'IP help' => 'The IP address or IP-ranges you wish to ban (e.g. 150.11.110.1 or 150.11.110). Separate addresses with spaces. If an IP is entered already it is the last known IP of this user in the database.', +'IP help link' => 'Click %s to see IP statistics for this user.', +'Ban advanced head' => 'Ban advanced settings', +'Ban advanced subhead' => 'Supplement ban with IP and email', +'Ban message label' => 'Ban message', +'Ban message help' => 'A message that will be displayed to the banned user when he/she visits the board.', +'Message expiry subhead' => 'Ban message and expiry', +'Ban IP range info' => 'You should be very careful when banning an IP-range because of the possibility of multiple users matching the same partial IP.', +'Expire date label' => 'Expire date', +'Expire date help' => 'The date when this ban should be automatically removed (format: yyyy-mm-dd). Leave blank to remove manually.', + +'Results head' => 'Search Results', +'Results username head' => 'Username', +'Results e-mail head' => 'Email', +'Results IP address head' => 'IP/IP-ranges', +'Results expire head' => 'Expires', +'Results message head' => 'Message', +'Results banned by head' => 'Banned by', +'Results actions head' => 'Actions', +'No match' => 'No match', +'Unknown' => 'Unknown', + +); diff --git a/lang/English/admin_categories.php b/lang/English/admin_categories.php new file mode 100644 index 0000000..311a5af --- /dev/null +++ b/lang/English/admin_categories.php @@ -0,0 +1,29 @@ + 'You must enter a name for the category', +'Category added redirect' => 'Category added. Redirecting …', +'Category deleted redirect' => 'Category deleted. Redirecting …', +'Delete category head' => 'Delete category (together with all forums and posts it contains)', +'Confirm delete subhead' => 'Confirm delete category', +'Confirm delete info' => 'Are you sure that you want to delete the category %s?', +'Delete category warn' => 'WARNING! Deleting a category will delete all forums and posts (if any) in this category!', +'Must enter integer message' => 'Position must be a positive integer value.', +'Categories updated redirect' => 'Categories updated. Redirecting …', +'Add categories head' => 'Add categories', +'Add categories subhead' => 'Add categories', +'Add category label' => 'Add a new category', +'Add new submit' => 'Add new', +'Add category help' => 'The name of the new category you want to add. You can edit the name of the category later (see below). Go to %s to add forums to your new category.', +'Delete categories head' => 'Delete categories', +'Delete categories subhead' => 'Delete categories', +'Delete category label' => 'Delete a category', +'Delete category help' => 'Select the name of the category you want to delete. You will be asked to confirm your choice of category for deletion before it is deleted.', +'Edit categories head' => 'Edit categories', +'Edit categories subhead' => 'Edit categories', +'Category position label' => 'Position', +'Category name label' => 'Name', + +); diff --git a/lang/English/admin_censoring.php b/lang/English/admin_censoring.php new file mode 100644 index 0000000..f112ba1 --- /dev/null +++ b/lang/English/admin_censoring.php @@ -0,0 +1,20 @@ + 'You must enter both a word to censor and text to replace it with.', +'Must search both message' => 'You must enter both text to search for and text to replace with.', +'Word updated redirect' => 'Censor word updated. Redirecting …', +'Word added redirect' => 'Censor word added. Redirecting …', +'Word removed redirect' => 'Censor word removed. Redirecting …', +'Censoring head' => 'Censoring', +'Add word subhead' => 'Add word', +'Add word info' => 'Enter a word that you want to censor and the replacement text for this word. Wildcards are accepted (i.e. *some* would match somewhere and lonesome). Censor words also affect usernames. New users will not be able to register with usernames containing any censored words. The search is case insensitive. Censor words must be enabled in %s for this to have any effect.', +'Censored word label' => 'Censored word', +'Replacement label' => 'Replacement word(s)', +'Action label' => 'Action', +'Edit remove subhead' => 'Edit or remove words', +'No words in list' => 'No censor words in list.', + +); diff --git a/lang/English/admin_common.php b/lang/English/admin_common.php new file mode 100644 index 0000000..a87616c --- /dev/null +++ b/lang/English/admin_common.php @@ -0,0 +1,44 @@ + 'Admin menu', +'Plugins menu' => 'Plugins menu', +'Moderator menu' => 'Moderator menu', +'Index' => 'Index', +'Categories' => 'Categories', +'Forums' => 'Forums', +'Users' => 'Users', +'User groups' => 'User groups', +'Options' => 'Options', +'Permissions' => 'Permissions', +'Censoring' => 'Censoring', +'Ranks' => 'Ranks', +'Bans' => 'Bans', +'Prune' => 'Prune', +'Maintenance' => 'Maintenance', +'Reports' => 'Reports', + +'Admin' => 'Admin', +'Go back' => 'Go back', +'Delete' => 'Delete', +'Update' => 'Update', +'Add' => 'Add', +'Edit' => 'Edit', +'Remove' => 'Remove', +'Yes' => 'Yes', +'No' => 'No', +'Save changes' => 'Save changes', +'Save' => 'Save', +'here' => 'here', +'Action' => 'Action', +'None' => 'None', +'Maintenance mode' => 'maintenance mode', // Used for link text in more than one file + +// Admin loader +'No plugin message' => 'There is no plugin called %s in the plugin directory.', +'Plugin failed message' => 'Loading of the plugin - %s - failed.', + +); diff --git a/lang/English/admin_forums.php b/lang/English/admin_forums.php new file mode 100644 index 0000000..f13876d --- /dev/null +++ b/lang/English/admin_forums.php @@ -0,0 +1,51 @@ + 'Forum added. Redirecting …', +'Forum deleted redirect' => 'Forum deleted. Redirecting …', +'Forums updated redirect' => 'Forums updated. Redirecting …', +'Forum updated redirect' => 'Forum updated. Redirecting …', +'Perms reverted redirect' => 'Permissions reverted to defaults. Redirecting …', +'Must enter name message' => 'You must enter a forum name.', +'Must be integer message' => 'Position must be a positive integer value.', + +// Entry page +'Add forum head' => 'Add forum', +'Create new subhead' => 'Create a new forum', +'Add forum label' => 'Add forum to category', +'Add forum help' => 'Select the category to which you wish to add a new forum.', +'Add forum' => 'Add forum', +'No categories exist' => 'No categories exist', +'Edit forums head' => 'Edit forums', +'Category subhead' => 'Category:', +'Forum label' => 'Forum', +'Edit link' => 'Edit', +'Delete link' => 'Delete', +'Position label' => 'Position', +'Update positions' => 'Update positions', +'Confirm delete head' => 'Confirm delete forum', +'Confirm delete subhead' => 'Important! Read before deleting', +'Confirm delete info' => 'Are you sure that you want to delete the forum %s?', +'Confirm delete warn' => 'WARNING! Deleting a forum will delete all posts (if any) in that forum!', + +// Detailed edit page +'Edit forum head' => 'Edit forum', +'Edit details subhead' => 'Edit forum details', +'Forum name label' => 'Forum name', +'Forum description label' => 'Description (HTML)', +'Category label' => 'Category', +'Sort by label' => 'Sort topics by', +'Last post' => 'Last post', +'Topic start' => 'Topic start', +'Redirect label' => 'Redirect URL', +'Redirect help' => 'Only available in empty forums', +'Group permissions subhead' => 'Edit group permissions for this forum', +'Group permissions info' => 'In this form, you can set the forum specific permissions for the different user groups. If you haven\'t made any changes to this forum\'s group permissions, what you see below is the default based on settings in %s. Administrators always have full permissions and are thus excluded. Permission settings that differ from the default permissions for the user group are marked red. The "Read forum" permission checkbox will be disabled if the group in question lacks the "Read board" permission. For redirect forums, only the "Read forum" permission is editable.', +'Read forum label' => 'Read forum', +'Post replies label' => 'Post replies', +'Post topics label' => 'Post topics', +'Revert to default' => 'Revert to default', + +); diff --git a/lang/English/admin_groups.php b/lang/English/admin_groups.php new file mode 100644 index 0000000..dd6ad56 --- /dev/null +++ b/lang/English/admin_groups.php @@ -0,0 +1,82 @@ + 'You must enter a group title.', +'Title already exists message' => 'There is already a group with the title %s.', +'Default group redirect' => 'Default group set. Redirecting …', +'Cannot remove default message' => 'The default group cannot be removed. In order to delete this group, you must first setup a different group as the default.', +'Group removed redirect' => 'Group removed. Redirecting …', +'Group added redirect' => 'Group added. Redirecting …', +'Group edited redirect' => 'Group edited. Redirecting …', + +'Add groups head' => 'Add/setup groups', +'Add group subhead' => 'Add new group', +'New group label' => 'Base new group on', +'New group help' => 'Select a user group from which the new group will inherit its permission settings. The next page will let you fine-tune its settings.', +'Default group subhead' => 'Set default group', +'Default group label' => 'Default group', +'Default group help' => 'This is the default user group, e.g. the group users are placed in when they register. For security reasons, users can\'t be placed in either the moderator or administrator user groups by default.', +'Existing groups head' => 'Existing groups', +'Edit groups subhead' => 'Edit/delete groups', +'Edit groups info' => 'The pre-defined groups Guests, Administrators, Moderators and Members cannot be removed. However, they can be edited. Please note that in some groups, some options are unavailable (e.g. the edit posts permission for guests). Administrators always have full permissions.', +'Edit link' => 'Edit', +'Delete link' => 'Delete', +'Group delete head' => 'Group delete', +'Confirm delete subhead' => 'Confirm delete group', +'Confirm delete info' => 'Are you sure that you want to delete the group %s?', +'Confirm delete warn' => 'WARNING! After you deleted a group you can not restore it.', +'Delete group head' => 'Delete group', +'Move users subhead' => 'Move users currently in group', +'Move users info' => 'The group %s currently has %s members. Please select a group to which these members will be assigned upon deletion.', +'Move users label' => 'Move users to', +'Delete group' => 'Delete group', + +'Group settings head' => 'Group settings', +'Group settings subhead' => 'Setup group options and permissions', +'Group settings info' => 'Below options and permissions are the default permissions for the user group. These options apply if no forum specific permissions are in effect.', +'Group title label' => 'Group title', +'User title label' => 'User title', +'User title help' => 'This title will override any rank users in this group have attained. Leave blank to use default title or rank.', +'Mod privileges label' => 'Allow users moderator privileges', +'Mod privileges help' => 'In order for a user in this group to have moderator abilities, he/she must be assigned to moderate one or more forums. This is done via the user administration page of the user\'s profile.', +'Edit profile label' => 'Allow moderators to edit user profiles', +'Edit profile help' => 'If moderator privileges are enabled, allow users in this group to edit user profiles.', +'Rename users label' => 'Allow moderators to rename users', +'Rename users help' => 'If moderator privileges are enabled, allow users in this group to rename users.', +'Change passwords label' => 'Allow moderators to change passwords', +'Change passwords help' => 'If moderator privileges are enabled, allow users in this group to change user passwords.', +'Ban users label' => 'Allow moderators to ban users', +'Ban users help' => 'If moderator privileges are enabled, allow users in this group to ban users.', +'Read board label' => 'Read board', +'Read board help' => 'Allow users in this group to view the board. This setting applies to every aspect of the board and can therefore not be overridden by forum specific settings. If this is set to "No", users in this group will only be able to login/logout and register.', +'View user info label' => 'View user information', +'View user info help' => 'Allow users to view the user list and user profiles.', +'Post replies label' => 'Post replies', +'Post replies help' => 'Allow users in this group to post replies in topics.', +'Post topics label' => 'Post topics', +'Post topics help' => 'Allow users in this group to post new topics.', +'Edit posts label' => 'Edit posts', +'Edit posts help' => 'Allow users in this group to edit their own posts.', +'Delete posts label' => 'Delete posts', +'Delete posts help' => 'Allow users in this group to delete their own posts.', +'Delete topics label' => 'Delete topics', +'Delete topics help' => 'Allow users in this group to delete their own topics (including any replies).', +'Set own title label' => 'Set own user title', +'Set own title help' => 'Allow users in this group to set their own user title.', +'User search label' => 'Use search', +'User search help' => 'Allow users in this group to use the search feature.', +'User list search label' => 'Search user list', +'User list search help' => 'Allow users in this group to freetext search for users in the user list.', +'Send e-mails label' => 'Send e-mails', +'Send e-mails help' => 'Allow users in this group to send e-mails to other users.', +'Post flood label' => 'Post flood interval', +'Post flood help' => 'Number of seconds that users in this group have to wait between posts. Set to 0 to disable.', +'Search flood label' => 'Search flood interval', +'Search flood help' => 'Number of seconds that users in this group have to wait between searches. Set to 0 to disable.', +'E-mail flood label' => 'Email flood interval', +'E-mail flood help' => 'Number of seconds that users in this group have to wait between emails. Set to 0 to disable.', +'Moderator info' => 'Please note that in order for a user in this group to have moderator abilities, he/she must be assigned to moderate one or more forums. This is done via the user administration page of the user\'s profile.', + +); diff --git a/lang/English/admin_index.php b/lang/English/admin_index.php new file mode 100644 index 0000000..9f9cdc7 --- /dev/null +++ b/lang/English/admin_index.php @@ -0,0 +1,51 @@ + 'Unable to check for upgrade since \'allow_url_fopen\' is disabled on this system.', +'Upgrade check failed message' => 'Check for upgrade failed for unknown reasons.', +'Running latest version message' => 'You are running the latest version of FluxBB.', +'New version available message' => 'A new version of FluxBB has been released. You can download the latest version at %s.', +'PHPinfo disabled message' => 'The PHP function phpinfo() has been disabled on this server.', +'Not available' => 'Not available', +'Forum admin head' => 'Forum administration', +'NA' => 'N/A', +'Welcome to admin' => 'Welcome to the FluxBB administration control panel. From here you can control vital aspects of the board. Depending on whether you are an administrator or a moderator you can:', +'Welcome 1' => 'Organize categories and forums.', +'Welcome 2' => 'Set forum-wide options and preferences.', +'Welcome 3' => 'Control permissions for users and guests.', +'Welcome 4' => 'View IP statistics for users.', +'Welcome 5' => 'Ban users.', +'Welcome 6' => 'Censor words.', +'Welcome 7' => 'Set up user ranks.', +'Welcome 8' => 'Prune old posts.', +'Welcome 9' => 'Handle post reports.', +'Statistics head' => 'Statistics', +'FluxBB version label' => 'FluxBB version', +'Check for upgrade' => 'Check for upgrade', +'FluxBB version data' => 'v%s - %s', +'Server load label' => 'Server load', +'Server load data' => '%s - %s user(s) online', +'Environment label' => 'Environment', +'Environment data OS' => 'Operating system: %s', +'Show info' => 'Show info', +'Environment data version' => 'PHP: %s - %s', +'Environment data acc' => 'Accelerator: %s', +'Turck MMCache' => 'Turk MMCache', +'Turck MMCache link' => 'turck-mmcache.sourceforge.net', +'ionCube PHP Accelerator' => 'ionCube PHP Accelerator', +'ionCube PHP Accelerator link' => 'www.php-accelerator.co.uk/', +'Alternative PHP Cache (APC)' => 'Alternative PHP Cache (APC)', +'Alternative PHP Cache (APC) link' => 'www.php.net/apc/', +'Zend Optimizer' => 'Zend Optimizer', +'Zend Optimizer link' => 'www.zend.com/products/guard/zend-optimizer', +'eAccelerator' => 'eAccelerator', +'eAccelerator link' => 'www.eaccelerator.net/', +'XCache' => 'XCache', +'XCache link' => 'xcache.lighttpd.net/', +'Database label' => 'Database', +'Database data rows' => 'Rows: %s', +'Database data size' => 'Size: %s', + +); diff --git a/lang/English/admin_maintenance.php b/lang/English/admin_maintenance.php new file mode 100644 index 0000000..a0e62b3 --- /dev/null +++ b/lang/English/admin_maintenance.php @@ -0,0 +1,23 @@ + 'Forum maintenance', +'Rebuild index subhead' => 'Rebuild search index', +'Rebuild index info' => 'If you\'ve added, edited or removed posts manually in the database or if you\'re having problems searching, you should rebuild the search index. For best performance, you should put the forum in %s during rebuilding. Rebuilding the search index can take a long time and will increase server load during the rebuild process!', +'Posts per cycle label' => 'Posts per cycle', +'Posts per cycle help' => 'The number of posts to process per pageview. E.g. if you were to enter 300, three hundred posts would be processed and then the page would refresh. This is to prevent the script from timing out during the rebuild process.', +'Starting post label' => 'Starting post ID', +'Starting post help' => 'The post ID to start rebuilding at. The default value is the first available ID in the database. Normally you wouldn\'t want to change this.', +'Empty index label' => 'Empty index', +'Empty index help' => 'Select this if you want the search index to be emptied before rebuilding (see below).', +'Rebuild completed info' => 'Once the process has completed, you will be redirected back to this page. It is highly recommended that you have JavaScript enabled in your browser during rebuilding (for automatic redirect when a cycle has completed). If you are forced to abort the rebuild process, make a note of the last processed post ID and enter that ID+1 in "Starting post ID" when/if you want to continue ("Empty index" must not be selected).', +'Rebuild index' => 'Rebuild index', +'Rebuilding search index' => 'Rebuilding search index', +'Rebuilding index info' => 'Rebuilding index. This might be a good time to put on some coffee :-)', +'Processing post' => 'Processing post %s …', +'Click here' => 'Click here', +'Javascript redirect failed' => 'JavaScript redirect unsuccessful. %s to continue …', + +); diff --git a/lang/English/admin_options.php b/lang/English/admin_options.php new file mode 100644 index 0000000..e701917 --- /dev/null +++ b/lang/English/admin_options.php @@ -0,0 +1,217 @@ + 'Bad HTTP_REFERER. If you have moved these forums from one location to another or switched domains, you need to update the Base URL manually in the database (look for o_base_url in the config table) and then clear the cache by deleting all .php files in the /cache directory.', +'Must enter title message' => 'You must enter a board title.', +'Invalid e-mail message' => 'The admin email address you entered is invalid.', +'Invalid webmaster e-mail message' => 'The webmaster email address you entered is invalid.', +'Enter announcement here' => 'Enter your announcement here.', +'Enter rules here' => 'Enter your rules here.', +'Default maintenance message' => 'The forums are temporarily down for maintenance. Please try again in a few minutes.', +'Timeout error message' => 'The value of "Timeout online" must be smaller than the value of "Timeout visit".', +'Options updated redirect' => 'Options updated. Redirecting …', +'Options head' => 'Options', + +// Essentials section +'Essentials subhead' => 'Essentials', +'Board title label' => 'Board title', +'Board title help' => 'The title of this bulletin board (shown at the top of every page). This field may not contain HTML.', +'Board desc label' => 'Board description', +'Board desc help' => 'A short description of this bulletin board (shown at the top of every page). This field may contain HTML.', +'Base URL label' => 'Base URL', +'Base URL help' => 'The complete URL of the board without trailing slash (i.e. http://www.mydomain.com/forums). This must be correct in order for all admin and moderator features to work. If you get "Bad referer" errors, it\'s probably incorrect.', +'Timezone label' => 'Default time zone', +'Timezone help' => 'The default time zone for guests and users attempting to register for the board.', +'DST label' => 'Adjust for DST', +'DST help' => 'Check if daylight savings is in effect (advances times by 1 hour).', +'Language label' => 'Default language', +'Language help' => 'The default language for guests and users who haven\'t changed from the default in their profile. If you remove a language pack, this must be updated.', +'Default style label' => 'Default style', +'Default style help' => 'The default style for guests and users who haven\'t changed from the default in their profile.', + +// Essentials section timezone options +'UTC-12:00' => '(UTC-12:00) International Date Line West', +'UTC-11:00' => '(UTC-11:00) Niue, Samoa', +'UTC-10:00' => '(UTC-10:00) Hawaii-Aleutian, Cook Island', +'UTC-09:30' => '(UTC-09:30) Marquesas Islands', +'UTC-09:00' => '(UTC-09:00) Alaska, Gambier Island', +'UTC-08:30' => '(UTC-08:30) Pitcairn Islands', +'UTC-08:00' => '(UTC-08:00) Pacific', +'UTC-07:00' => '(UTC-07:00) Mountain', +'UTC-06:00' => '(UTC-06:00) Central', +'UTC-05:00' => '(UTC-05:00) Eastern', +'UTC-04:00' => '(UTC-04:00) Atlantic', +'UTC-03:30' => '(UTC-03:30) Newfoundland', +'UTC-03:00' => '(UTC-03:00) Amazon, Central Greenland', +'UTC-02:00' => '(UTC-02:00) Mid-Atlantic', +'UTC-01:00' => '(UTC-01:00) Azores, Cape Verde, Eastern Greenland', +'UTC' => '(UTC) Western European, Greenwich', +'UTC+01:00' => '(UTC+01:00) Central European, West African', +'UTC+02:00' => '(UTC+02:00) Eastern European, Central African', +'UTC+03:00' => '(UTC+03:00) Moscow, Eastern African', +'UTC+03:30' => '(UTC+03:30) Iran', +'UTC+04:00' => '(UTC+04:00) Gulf, Samara', +'UTC+04:30' => '(UTC+04:30) Afghanistan', +'UTC+05:00' => '(UTC+05:00) Pakistan, Yekaterinburg', +'UTC+05:30' => '(UTC+05:30) India, Sri Lanka', +'UTC+05:45' => '(UTC+05:45) Nepal', +'UTC+06:00' => '(UTC+06:00) Bangladesh, Bhutan, Novosibirsk', +'UTC+06:30' => '(UTC+06:30) Cocos Islands, Myanmar', +'UTC+07:00' => '(UTC+07:00) Indochina, Krasnoyarsk', +'UTC+08:00' => '(UTC+08:00) Greater China, Australian Western, Irkutsk', +'UTC+08:45' => '(UTC+08:45) Southeastern Western Australia', +'UTC+09:00' => '(UTC+09:00) Japan, Korea, Chita', +'UTC+09:30' => '(UTC+09:30) Australian Central', +'UTC+10:00' => '(UTC+10:00) Australian Eastern, Vladivostok', +'UTC+10:30' => '(UTC+10:30) Lord Howe', +'UTC+11:00' => '(UTC+11:00) Solomon Island, Magadan', +'UTC+11:30' => '(UTC+11:30) Norfolk Island', +'UTC+12:00' => '(UTC+12:00) New Zealand, Fiji, Kamchatka', +'UTC+12:45' => '(UTC+12:45) Chatham Islands', +'UTC+13:00' => '(UTC+13:00) Tonga, Phoenix Islands', +'UTC+14:00' => '(UTC+14:00) Line Islands', + +// Timeout Section +'Timeouts subhead' => 'Time and timeouts', +'Time format label' => 'Time format', +'PHP manual' => 'PHP manual', +'Time format help' => '[Current format: %s]. See %s for formatting options.', +'Date format label' => 'Date format', +'Date format help' => '[Current format: %s]. See %s for formatting options.', +'Visit timeout label' => 'Visit timeout', +'Visit timeout help' => 'Number of seconds a user must be idle before his/hers last visit data is updated (primarily affects new message indicators).', +'Online timeout label' => 'Online timeout', +'Online timeout help' => 'Number of seconds a user must be idle before being removed from the online users list.', +'Redirect time label' => 'Redirect time', +'Redirect time help' => 'Number of seconds to wait when redirecting. If set to 0, no redirect page will be displayed (not recommended).', + +// Display Section +'Display subhead' => 'Display', +'Version number label' => 'Version number', +'Version number help' => 'Show FluxBB version number in footer.', +'Info in posts label' => 'User info in posts', +'Info in posts help' => 'Show information about the poster under the username in topic view. The information affected is location, register date, post count and the contact links (email and URL).', +'Post count label' => 'User post count', +'Post count help' => 'Show the number of posts a user has made (affects topic view, profile and user list).', +'Smilies label' => 'Smilies in posts', +'Smilies help' => 'Convert smilies to small graphic icons.', +'Smilies sigs label' => 'Smilies in signatures', +'Smilies sigs help' => 'Convert smilies to small graphic icons in user signatures.', +'Clickable links label' => 'Make clickable links', +'Clickable links help' => 'When enabled, FluxBB will automatically detect any URLs in posts and make them clickable hyperlinks.', +'Topic review label' => 'Topic review', +'Topic review help' => 'Maximum number of posts to display when posting (newest first). Set to 0 to disable.', +'Topics per page label' => 'Topics per page', +'Topics per page help' => 'The default number of topics to display per page in a forum. Users can personalize this setting.', +'Posts per page label' => 'Posts per page', +'Posts per page help' => 'The default number of posts to display per page in a topic. Users can personalize this setting.', +'Indent label' => 'Indent size', +'Indent help' => 'If set to 8, a regular tab will be used when displaying text within the [code][/code] tag. Otherwise this many spaces will be used to indent the text.', +'Quote depth label' => 'Maximum [quote] depth', +'Quote depth help' => 'The maximum times a [quote] tag can go inside other [quote] tags, any tags deeper than this will be discarded.', + +// Features section +'Features subhead' => 'Features', +'Quick post label' => 'Quick post', +'Quick post help' => 'When enabled, FluxBB will add a quick post form at the bottom of topics. This way users can post directly from the topic view.', +'Users online label' => 'Users online', +'Users online help' => 'Display info on the index page about guests and registered users currently browsing the board.', +'Censor words label' => 'Censor words', +'Censor words help' => 'Enable this to censor specific words in the board. See %s for more info.', +'Signatures label' => 'Signatures', +'Signatures help' => 'Allow users to attach a signature to their posts.', +'User ranks label' => 'User ranks', +'User ranks help' => 'Enable this to use user ranks. See %s for more info.', +'User has posted label' => 'User has posted earlier', +'User has posted help' => 'This feature displays a dot in front of topics in viewforum.php in case the currently logged in user has posted in that topic earlier. Disable if you are experiencing high server load.', +'Topic views label' => 'Topic views', +'Topic views help' => 'Keep track of the number of views a topic has. Disable if you are experiencing high server load in a busy forum.', +'Quick jump label' => 'Quick jump', +'Quick jump help' => 'Enable the quick jump (jump to forum) drop list.', +'GZip label' => 'GZip output', +'GZip help' => 'If enabled, FluxBB will gzip the output sent to browsers. This will reduce bandwidth usage, but use a little more CPU. This feature requires that PHP is configured with zlib (--with-zlib). Note: If you already have one of the Apache modules mod_gzip or mod_deflate set up to compress PHP scripts, you should disable this feature.', +'Search all label' => 'Search all forums', +'Search all help' => 'When disabled, searches will only be allowed in one forum at a time. Disable if server load is high due to excessive searching.', +'Menu items label' => 'Additional menu items', +'Menu items help' => 'By entering HTML hyperlinks into this textbox, any number of items can be added to the navigation menu at the top of all pages. The format for adding new links is X = <a href="URL">LINK</a> where X is the position at which the link should be inserted (e.g. 0 to insert at the beginning and 2 to insert after "User list"). Separate entries with a linebreak.', +'Default feed label' => 'Default feed type', +'Default feed help' => 'Select the type of syndication feed to display. Note: Choosing none will not disable feeds, only hide them by default.', +'None' => 'None', +'RSS' => 'RSS', +'Atom' => 'Atom', + +// Reports section +'Reports subhead' => 'Reports', +'Reporting method label' => 'Reporting method', +'Internal' => 'Internal', +'By e-mail' => 'Email', +'Both' => 'Both', +'Reporting method help' => 'Select the method for handling topic/post reports. You can choose whether topic/post reports should be handled by the internal report system, emailed to the addresses on the mailing list (see below) or both.', +'Mailing list label' => 'Mailing list', +'Mailing list help' => 'A comma separated list of subscribers. The people on this list are the recipients of reports.', + +// Avatars section +'Avatars subhead' => 'Avatars', +'Use avatars label' => 'Use avatars', +'Use avatars help' => 'When enabled, users will be able to upload an avatar which will be displayed under their title/rank.', +'Upload directory label' => 'Upload directory', +'Upload directory help' => 'The upload directory for avatars (relative to the FluxBB root directory). PHP must have write permissions to this directory.', +'Max width label' => 'Max width', +'Max width help' => 'The maximum allowed width of avatars in pixels (60 is recommended).', +'Max height label' => 'Max height', +'Max height help' => 'The maximum allowed height of avatars in pixels (60 is recommended).', +'Max size label' => 'Max size', +'Max size help' => 'The maximum allowed size of avatars in bytes (10240 is recommended).', + +// E-mail section +'E-mail subhead' => 'Email', +'Admin e-mail label' => 'Admin email', +'Admin e-mail help' => 'The email address of the board administrator.', +'Webmaster e-mail label' => 'Webmaster email', +'Webmaster e-mail help' => 'This is the address that all emails sent by the board will be addressed from.', +'Subscriptions label' => 'Subscriptions', +'Subscriptions help' => 'Enable users to subscribe to topics (receive email when someone replies).', +'SMTP address label' => 'SMTP server address', +'SMTP address help' => 'The address of an external SMTP server to send emails with. You can specify a custom port number if the SMTP server doesn\'t run on the default port 25 (example: mail.myhost.com:3580). Leave blank to use the local mail program.', +'SMTP username label' => 'SMTP username', +'SMTP username help' => 'Username for SMTP server. Only enter a username if it is required by the SMTP server (most servers do not require authentication).', +'SMTP password label' => 'SMTP password', +'SMTP password help' => 'Password for SMTP server. Only enter a password if it is required by the SMTP server (most servers do not require authentication).', +'SMTP SSL label' => 'Encrypt SMTP using SSL', +'SMTP SSL help' => 'Encrypts the connection to the SMTP server using SSL. Should only be used if your SMTP server requires it and your version of PHP supports SSL.', + +// Registration Section +'Registration subhead' => 'Registration', +'Allow new label' => 'Allow new registrations', +'Allow new help' => 'Controls whether this board accepts new registrations. Disable only under special circumstances.', +'Verify label' => 'Verify registrations', +'Verify help' => 'When enabled, users are emailed a random password when they register. They can then log in and change the password in their profile if they see fit. This feature also requires users to verify new email addresses if they choose to change from the one they registered with. This is an effective way of avoiding registration abuse and making sure that all users have "correct" email addresses in their profiles.', +'Report new label' => 'Report new registrations', +'Report new help' => 'If enabled, FluxBB will notify users on the mailing list (see above) when a new user registers in the forums.', +'Use rules label' => 'User forum rules', +'Use rules help' => 'When enabled, users must agree to a set of rules when registering (enter text below). The rules will always be available through a link in the navigation table at the top of every page.', +'Rules label' => 'Enter your rules here', +'Rules help' => 'Here you can enter any rules or other information that the user must review and accept when registering. If you enabled rules above you have to enter something here, otherwise it will be disabled. This text will not be parsed like regular posts and thus may contain HTML.', +'E-mail default label' => 'Default email setting', +'E-mail default help' => 'Choose the default privacy setting for new user registrations.', +'Display e-mail label' => 'Display email address to other users.', +'Hide allow form label' => 'Hide email address but allow form e-mail.', +'Hide both label' => 'Hide email address and disallow form email.', + +// Announcement Section +'Announcement subhead' => 'Announcements', +'Display announcement label' => 'Display announcement', +'Display announcement help' => 'Enable this to display the below message in the board.', +'Announcement message label' => 'Announcement message', +'Announcement message help' => 'This text will not be parsed like regular posts and thus may contain HTML.', + +// Maintenance Section +'Maintenance subhead' => 'Maintenance', +'Maintenance mode label' => 'Maintenance mode', +'Maintenance mode help' => 'When enabled, the board will only be available to administrators. This should be used if the board needs to be taken down temporarily for maintenance. WARNING! Do not log out when the board is in maintenance mode. You will not be able to login again.', +'Maintenance message label' => 'Maintenance message', +'Maintenance message help' => 'The message that will be displayed to users when the board is in maintenance mode. If left blank, a default message will be used. This text will not be parsed like regular posts and thus may contain HTML.', + +); diff --git a/lang/English/admin_permissions.php b/lang/English/admin_permissions.php new file mode 100644 index 0000000..3c3600c --- /dev/null +++ b/lang/English/admin_permissions.php @@ -0,0 +1,36 @@ + 'Permissions updated. Redirecting …', +'Permissions head' => 'Permissions', +'Posting subhead' => 'Posting', +'BBCode label' => 'BBCode', +'BBCode help' => 'Allow BBCode in posts (recommended).', +'Image tag label' => 'Image tag', +'Image tag help' => 'Allow the BBCode [img][/img] tag in posts.', +'All caps message label' => 'All caps message', +'All caps message help' => 'Allow a message to contain only capital letters.', +'All caps subject label' => 'All caps subject', +'All caps subject help' => 'Allow a subject to contain only capital letters.', +'Require e-mail label' => 'Require guest email', +'Require e-mail help' => 'Require guests to supply an email address when posting.', +'Signatures subhead' => 'Signatures', +'BBCode sigs label' => 'BBCodes in signatures', +'BBCode sigs help' => 'Allow BBCodes in user signatures.', +'Image tag sigs label' => 'Image tag in signatures', +'Image tag sigs help' => 'Allow the BBCode [img][/img] tag in user signatures (not recommended).', +'All caps sigs label' => 'All caps signature', +'All caps sigs help' => 'Allow a signature to contain only capital letters.', +'Max sig length label' => 'Maximum signature length', +'Max sig length help' => 'The maximum number of characters a user signature may contain.', +'Max sig lines label' => 'Maximum signature lines', +'Max sig lines help' => 'The maximum number of lines a user signature may contain.', +'Registration subhead' => 'Registration', +'Banned e-mail label' => 'Allow banned email addresses', +'Banned e-mail help' => 'Allow users to register with or change to a banned email address/domain. If left at its default setting (yes), this action will be allowed, but an alert email will be sent to the mailing list (an effective way of detecting multiple registrations).', +'Duplicate e-mail label' => 'Allow duplicate email addresses', +'Duplicate e-mail help' => 'Controls whether users should be allowed to register with an email address that another user already has. If allowed, an alert email will be sent to the mailing list if a duplicate is detected.', + +); diff --git a/lang/English/admin_plugin_example.php b/lang/English/admin_plugin_example.php new file mode 100644 index 0000000..b06158d --- /dev/null +++ b/lang/English/admin_plugin_example.php @@ -0,0 +1,17 @@ + 'You didn\'t enter anything!', +'Example plugin title' => 'Example plugin', +'You said' => 'You said "%s". Great stuff.', +'Explanation 1' => 'This plugin doesn\'t do anything useful. Hence the name "Example".', +'Explanation 2' => 'This would be a good spot to talk a little about your plugin. Describe what it does and how it should be used. Be brief, but informative.', +'Example form title' => 'An example form', +'Legend text' => 'Enter a piece of text and hit "Show text"!', +'Text to show' => 'Text to show', +'Show text button' => 'Show text', +'Input content' => 'The text you want to display.', + +); diff --git a/lang/English/admin_prune.php b/lang/English/admin_prune.php new file mode 100644 index 0000000..b7f9030 --- /dev/null +++ b/lang/English/admin_prune.php @@ -0,0 +1,23 @@ + 'Days to prune must be a positive integer value.', +'No old topics message' => 'There are no topics that are %s days old. Please decrease the value of "Days old" and try again.', +'Posts pruned redirect' => 'Posts pruned. Redirecting …', +'Prune head' => 'Prune', +'Prune subhead' => 'Prune old posts', +'Days old label' => 'Days old', +'Days old help' => 'The number of days "old" a topic must be to be pruned. E.g. if you were to enter 30, every topic that didn\'t contain a post dated less than 30 days old would be deleted.', +'Prune sticky label' => 'Prune sticky topics', +'Prune sticky help' => 'When enabled sticky topics will also be pruned.', +'Prune from label' => 'Prune from forum', +'All forums' => 'All forums', +'Prune from help' => 'The forum from which you want to prune posts.', +'Prune info' => 'Use this feature with caution. Pruned posts can never be recovered. For best performance, you should put the forum in %s during pruning.', +'Confirm prune subhead' => 'Confirm prune posts', +'Confirm prune info' => 'Are you sure that you want to prune all topics older than %s days from %s (%s topics).', +'Confirm prune warn' => 'WARNING! Pruning posts deletes them permanently.', + +); diff --git a/lang/English/admin_ranks.php b/lang/English/admin_ranks.php new file mode 100644 index 0000000..7dca408 --- /dev/null +++ b/lang/English/admin_ranks.php @@ -0,0 +1,21 @@ + 'Minimum posts must be a positive integer value.', +'Dupe min posts message' => 'There is already a rank with a minimun posts value of %s.', +'Must enter title message' => 'You must enter a rank title.', +'Rank added redirect' => 'Rank added. Redirecting …', +'Rank updated redirect' => 'Rank updated. Redirecting …', +'Rank removed redirect' => 'Rank removed. Redirecting …', +'Ranks head' => 'Ranks', +'Add rank subhead' => 'Add rank', +'Add rank info' => 'Enter a rank and the minimum number of posts a user must have made to attain the rank. Different ranks cannot have the same value for minimum posts. If a title is set for a user, the title will be displayed instead of any rank. User ranks must be enabled in %s for this to have any effect.', +'Rank title label' => 'Rank title', +'Minimum posts label' => 'Minimum posts', +'Actions label' => 'Actions', +'Edit remove subhead' => 'Edit/remove ranks', +'No ranks in list' => 'No ranks in list', + +); diff --git a/lang/English/admin_reports.php b/lang/English/admin_reports.php new file mode 100644 index 0000000..152bab3 --- /dev/null +++ b/lang/English/admin_reports.php @@ -0,0 +1,20 @@ + 'Report zapped. Redirecting …', +'New reports head' => 'New reports', +'Deleted user' => 'Deleted user', +'Deleted' => 'Deleted', +'Report subhead' => 'Reported %s', +'Reported by' => 'Reported by %s', +'Reason' => 'Reason', +'Zap' => 'Zap', +'No new reports' => 'There are no new reports.', +'Last 10 head' => '10 last zapped reports', +'NA' => 'N/A', +'Zapped subhead' => 'Zapped %s by %s', +'No zapped reports' => 'There are no zapped reports.', + +); \ No newline at end of file diff --git a/lang/English/admin_users.php b/lang/English/admin_users.php new file mode 100644 index 0000000..1e21a34 --- /dev/null +++ b/lang/English/admin_users.php @@ -0,0 +1,70 @@ + 'You entered a non-numeric value into a numeric only column.', +'Invalid date time message' => 'You entered an invalid date/time.', +'Not verified' => 'Not verified', +'User search head' => 'User search', +'User search subhead' => 'Enter search criteria', +'User search info' => 'Search for users in the database. You can enter one or more terms to search for. Wildcards in the form of asterisks (*) are accepted.', +'Username label' => 'Username', +'E-mail address label' => 'Email address', +'Title label' => 'Title', +'Real name label' => 'Real name', +'Website label' => 'Website', +'Jabber label' => 'Jabber', +'ICQ label' => 'ICQ', +'MSN label' => 'MSN Messenger', +'AOL label' => 'AOL IM', +'Yahoo label' => 'Yahoo Messenger', +'Location label' => 'Location', +'Signature label' => 'Signature', +'Admin note label' => 'Admin note', +'Posts more than label' => 'Number of posts greater than', +'Posts less than label' => 'Number of posts less than', +'Last post after label' => 'Last post is after', +'Date help' => '(yyyy-mm-dd hh:mm:ss)', +'Last post before label' => 'Last post is before', +'Registered after label' => 'Registered after', +'Registered before label' => 'Registered before', +'Order by label' => 'Order by', +'Order by username' => 'Username', +'Order by e-mail' => 'Email', +'Order by posts' => 'Number of posts', +'Order by last post' => 'Last post', +'Order by registered' => 'Registered', +'Ascending' => 'Ascending', +'Descending' => 'Descending', +'User group label' => 'User group', +'All groups' => 'All groups', +'Unverified users' => 'Unverified users', +'Submit search' => 'Submit search', +'IP search head' => 'IP search', +'IP search subhead' => 'Enter IP to search for', +'IP address label' => 'IP address', +'IP address help' => 'The IP address to search for in the post database.', +'Find IP address' => 'Find IP address', + +'Results head' => 'Search Results', +'Results username head' => 'Username', +'Results e-mail head' => 'Email', +'Results title head' => 'Title/Status', +'Results posts head' => 'Posts', +'Results admin note head' => 'Admin note', +'Results actions head' => 'Actions', +'Results IP address head' => 'IP address', +'Results last used head' => 'Last used', +'Results times found head' => 'Times found', +'Results action head' => 'Action', +'Results find more link' => 'Find more users for this ip', +'Results no posts found' => 'There are currently no posts by that user in the forum.', +'Bad IP message' => 'The supplied IP address is not correctly formatted.', +'Results view IP link' => 'View IP stats', +'Results show posts link' => 'Show posts', +'Results guest' => 'Guest', +'Results no IP found' => 'The supplied IP address could not be found in the database.', +'No match' => 'No match' + +); diff --git a/lang/English/common.php b/lang/English/common.php new file mode 100644 index 0000000..85c276f --- /dev/null +++ b/lang/English/common.php @@ -0,0 +1,169 @@ + 'ltr', // ltr (Left-To-Right) or rtl (Right-To-Left) +'lang_identifier' => 'en', + +// Number formatting +'lang_decimal_point' => '.', +'lang_thousands_sep' => ',', + +// Notices +'Bad request' => 'Bad request. The link you followed is incorrect or outdated.', +'No view' => 'You do not have permission to view these forums.', +'No permission' => 'You do not have permission to access this page.', +'Bad referrer' => 'Bad HTTP_REFERER. You were referred to this page from an unauthorized source. If the problem persists please make sure that \'Base URL\' is correctly set in Admin/Options and that you are visiting the forum by navigating to that URL. More information regarding the referrer check can be found in the FluxBB documentation.', +'No cookie' => 'You appear to have logged in successfully, however a cookie has not been set. Please check your settings and if applicable, enable cookies for this website.', +'Pun include error' => 'Unable to process user include %s from template %s. There is no such file in neither the template directory nor in the user include directory.', + +// Miscellaneous +'Announcement' => 'Announcement', +'Options' => 'Options', +'Submit' => 'Submit', // "Name" of submit buttons +'Ban message' => 'You are banned from this forum.', +'Ban message 2' => 'The ban expires at the end of', +'Ban message 3' => 'The administrator or moderator that banned you left the following message:', +'Ban message 4' => 'Please direct any inquiries to the forum administrator at', +'Never' => 'Never', +'Today' => 'Today', +'Yesterday' => 'Yesterday', +'Info' => 'Info', // A common table header +'Go back' => 'Go back', +'Maintenance' => 'Maintenance', +'Redirecting' => 'Redirecting', +'Click redirect' => 'Click here if you do not want to wait any longer (or if your browser does not automatically forward you)', +'on' => 'on', // As in "BBCode is on" +'off' => 'off', +'Invalid email' => 'The email address you entered is invalid.', +'Required' => '(Required)', +'required field' => 'is a required field in this form.', // For javascript form validation +'Last post' => 'Last post', +'by' => 'by', // As in last post by someuser +'New posts' => 'New posts', // The link that leads to the first new post +'New posts info' => 'Go to the first new post in this topic.', // The popup text for new posts links +'Username' => 'Username', +'Password' => 'Password', +'Email' => 'Email', +'Send email' => 'Send email', +'Moderated by' => 'Moderated by', +'Registered' => 'Registered', +'Subject' => 'Subject', +'Message' => 'Message', +'Topic' => 'Topic', +'Forum' => 'Forum', +'Posts' => 'Posts', +'Replies' => 'Replies', +'Pages' => 'Pages:', +'Page' => 'Page %s', +'BBCode' => 'BBCode:', // You probably shouldn't change this +'img tag' => '[img] tag:', +'Smilies' => 'Smilies:', +'and' => 'and', +'Image link' => 'image', // This is displayed (i.e. ) instead of images when "Show images" is disabled in the profile +'wrote' => 'wrote:', // For [quote]'s +'Mailer' => 'Mailer', // As in "MyForums Mailer" in the signature of outgoing emails +'Important information' => 'Important information', +'Write message legend' => 'Write your message and submit', +'Previous' => 'Previous', +'Next' => 'Next', +'Spacer' => '…', // Ellipsis for paginate + +// Title +'Title' => 'Title', +'Member' => 'Member', // Default title +'Moderator' => 'Moderator', +'Administrator' => 'Administrator', +'Banned' => 'Banned', +'Guest' => 'Guest', + +// Stuff for include/parser.php +'BBCode error no opening tag' => '[/%1$s] was found without a matching [%1$s]', +'BBCode error invalid nesting' => '[%1$s] was opened within [%2$s], this is not allowed', +'BBCode error invalid self-nesting' => '[%s] was opened within itself, this is not allowed', +'BBCode error no closing tag' => '[%1$s] was found without a matching [/%1$s]', +'BBCode error empty attribute' => '[%s] tag had an empty attribute section', +'BBCode code problem' => 'There is a problem with your [code] tags', +'BBCode list size error' => 'Your list was too long to parse, please make it smaller!', + +// Stuff for the navigator (top of every page) +'Index' => 'Index', +'User list' => 'User list', +'Rules' => 'Rules', +'Search' => 'Search', +'Register' => 'Register', +'Login' => 'Login', +'Not logged in' => 'You are not logged in.', +'Profile' => 'Profile', +'Logout' => 'Logout', +'Logged in as' => 'Logged in as', +'Admin' => 'Administration', +'Last visit' => 'Last visit: %s', +'Show new posts' => 'Show new posts since last visit', +'Mark all as read' => 'Mark all topics as read', +'Mark forum read' => 'Mark this forum as read', +'Title separator' => ' / ', + +// Stuff for the page footer +'Board footer' => 'Board footer', +'Search links' => 'Search links', +'Show recent posts' => 'Show recent posts', +'Show unanswered posts' => 'Show unanswered posts', +'Show your posts' => 'Show your posts', +'Show subscriptions' => 'Show your subscribed topics', +'Jump to' => 'Jump to', +'Go' => ' Go ', // Submit button in forum jump +'Moderate topic' => 'Moderate topic', +'Move topic' => 'Move topic', +'Open topic' => 'Open topic', +'Close topic' => 'Close topic', +'Unstick topic' => 'Unstick topic', +'Stick topic' => 'Stick topic', +'Moderate forum' => 'Moderate forum', +'Powered by' => 'Powered by %s', + +// Debug information +'Debug table' => 'Debug information', +'Querytime' => 'Generated in %1$s seconds, %2$s queries executed', +'Memory usage' => 'Memory usage: %1$s', +'Peak usage' => '(Peak: %1$s)', +'Query times' => 'Time (s)', +'Query' => 'Query', +'Total query time' => 'Total query time: %s', + +// Email related notifications +'New user notification' => 'Alert - New registration', +'New user message' => 'User \'%s\' registered in the forums at %s', +'Banned email notification' => 'Alert - Banned email detected', +'Banned email register message' => 'User \'%s\' registered with banned email address: %s', +'Banned email change message' => 'User \'%s\' changed to banned email address: %s', +'Banned email post message' => 'User \'%s\' posted with banned email address: %s', +'Duplicate email notification' => 'Alert - Duplicate email detected', +'Duplicate email register message' => 'User \'%s\' registered with an email address that also belongs to: %s', +'Duplicate email change message' => 'User \'%s\' changed to an email address that also belongs to: %s', +'Report notification' => 'Report(%d) - \'%s\'', +'Report message 1' => 'User \'%s\' has reported the following message: %s', +'Report message 2' => 'Reason: %s', + +'User profile' => 'User profile: %s', +'Post URL' => 'Post URL: %s', +'Email signature' => 'Forum Mailer'."\n".'(Do not reply to this message)', + +// For extern.php RSS feed +'RSS description' => 'The most recent topics at %s.', +'RSS description topic' => 'The most recent posts in %s.', +'RSS reply' => 'Re: ', // The topic subject will be appended to this string (to signify a reply) +'RSS active topics feed' => 'RSS active topics feed', +'Atom active topics feed' => 'Atom active topics feed', +'RSS forum feed' => 'RSS forum feed', +'Atom forum feed' => 'Atom forum feed', +'RSS topic feed' => 'RSS topic feed', +'Atom topic feed' => 'Atom topic feed', + +// Admin related stuff in the header +'New reports' => 'There are new reports', +'Maintenance mode enabled' => 'Maintenance mode is enabled!', + +); diff --git a/lang/English/delete.php b/lang/English/delete.php new file mode 100644 index 0000000..61599d2 --- /dev/null +++ b/lang/English/delete.php @@ -0,0 +1,16 @@ + 'Delete post', +'Warning' => 'You are about to permanently delete this post.', +'Topic warning' => 'Warning! This is the first post in the topic, the whole topic will be permanently deleted.', +'Delete info' => 'The post you have chosen to delete is set out below for you to review before proceeding.', +'Reply by' => 'Reply by %s - %s', +'Topic by' => 'Topic started by %s - %s', +'Delete' => 'Delete', // The submit button +'Post del redirect' => 'Post deleted. Redirecting …', +'Topic del redirect' => 'Topic deleted. Redirecting …' + +); \ No newline at end of file diff --git a/lang/English/forum.php b/lang/English/forum.php new file mode 100644 index 0000000..42111da --- /dev/null +++ b/lang/English/forum.php @@ -0,0 +1,14 @@ + 'Post new topic', +'Views' => 'Views', +'Moved' => 'Moved:', +'Sticky' => 'Sticky:', +'Closed' => 'Closed:', +'Empty forum' => 'Forum is empty.', +'Mod controls' => 'Moderator controls' + +); diff --git a/lang/English/help.php b/lang/English/help.php new file mode 100644 index 0000000..47b5e0a --- /dev/null +++ b/lang/English/help.php @@ -0,0 +1,59 @@ + 'Help', +'produces' => 'produces', + +'BBCode' => 'BBCode', +'BBCode info 1' => 'BBCode is a collection of formatting tags that are used to change the look of text in this forum. BBCode is based on the same principal as, and is very similar to, HTML. Below is a list of all the available BBCodes and instructions on how to use them.', +'BBCode info 2' => 'Administrators have the ability to enable or disable BBCode. You can tell if BBCode is enabled or disabled out in the left margin whenever you post a message or edit your signature.', + +'Text style' => 'Text style', +'Text style info' => 'The following tags change the appearance of text:', +'Bold text' => 'Bold text', +'Underlined text' => 'Underlined text', +'Italic text' => 'Italic text', +'Strike-through text' => 'Strike-through text', +'Red text' => 'Red text', +'Blue text' => 'Blue text', +'Heading text' => 'Heading text', +'Deleted text' => 'Deleted text', +'Inserted text' => 'Inserted text', +'Emphasised text' => 'Emphasised text', + +'Links and images' => 'Links and images', +'Links info' => 'You can create links to other documents or to email addresses using the following tags:', +'My email address' => 'My email address', +'Images info' => 'If you want to display an image you can use the img tag. The text appearing after the "=" sign in the opening tag is used for the alt attribute and should be included whenever possible.', + +'Quotes' => 'Quotes', +'Quotes info' => 'If you want to quote someone, you should use the quote tag.', +'Quotes info 2' => 'If you don\'t want to quote anyone in particular, you can use the quote tag without specifying a name.', +'Quote text' => 'This is the text i want to quote.', +'produces quote box' => 'produces a quote box like this:', +'quote note' => 'Note: If a username contains the characters [ or ] you can enclose it in quote marks.', + +'Code' => 'Code', +'Code info' => 'When displaying source code you should make sure that you use the code tag. Text displayed with the code tag will use a monospaced font and will not be affected by other tags.', +'Code text' => 'This is some code.', +'produces code box' => 'produces a code box like this:', + +'Nested tags' => 'Nested tags', +'Nested tags info' => 'BBCode can be nested to create more advanced formatting. For example:', +'Bold, underlined text' => 'Bold, underlined text', + +'Lists' => 'Lists', +'List info' => 'To create a list you can use the list tag. You can create 3 types of lists using the list tag.', +'List text 1' => 'Example list item 1.', +'List text 2' => 'Example list item 2.', +'List text 3' => 'Example list item 3.', +'produces list' => 'produces a bulleted list.', +'produces decimal list' => 'produces a numbered list.', +'produces alpha list' => 'produces an alphabetically labelled list.', + +'Smilies' => 'Smilies', +'Smilies info' => 'If you like (and if it is enabled), the forum can convert a series of smilies to images representations of that smiley. This forum recognizes the following smilies and replaces them with images:' + +); diff --git a/lang/English/index.html b/lang/English/index.html new file mode 100644 index 0000000..89337b2 --- /dev/null +++ b/lang/English/index.html @@ -0,0 +1 @@ +.. diff --git a/lang/English/index.php b/lang/English/index.php new file mode 100644 index 0000000..0ed222a --- /dev/null +++ b/lang/English/index.php @@ -0,0 +1,20 @@ + 'Topics', +'Link to' => 'Link to:', // As in "Link to: http://fluxbb.org/" +'Empty board' => 'Board is empty.', +'Newest user' => 'Newest registered user: %s', +'Users online' => 'Registered users online: %s', +'Guests online' => 'Guests online: %s', +'No of users' => 'Total number of registered users: %s', +'No of topics' => 'Total number of topics: %s', +'No of posts' => 'Total number of posts: %s', +'Online' => 'Online:', // As in "Online: User A, User B etc." +'Board info' => 'Board information', +'Board stats' => 'Board statistics', +'User info' => 'User information' + +); diff --git a/lang/English/login.php b/lang/English/login.php new file mode 100644 index 0000000..244ee06 --- /dev/null +++ b/lang/English/login.php @@ -0,0 +1,26 @@ + 'Wrong username and/or password.', +'Forgotten pass' => 'Forgotten your password?', +'Login redirect' => 'Logged in successfully. Redirecting …', +'Logout redirect' => 'Logged out. Redirecting …', +'No email match' => 'There is no user registered with the email address', +'Request pass' => 'Request password', +'Request pass legend' => 'Enter the email address with which you registered', +'Request pass info' => 'A new password together with a link to activate the new password will be sent to that address.', +'Not registered' => 'Not registered yet?', +'Login legend' => 'Enter your username and password below', +'Remember me' => 'Log me in automatically each time I visit.', +'Login info' => 'If you have not registered or have forgotten your password click on the appropriate link below.', +'New password errors' => 'Password request error', +'New passworderrors info' => 'The following error needs to be corrected before a new password can be sent:', + +// Forget password mail stuff +'Forget mail' => 'An email has been sent to the specified address with instructions on how to change your password. If it does not arrive you can contact the forum administrator at', +'Email flood' => 'This account has already requested a password reset in the past hour. Please wait a while before requesting a new password again.' + +); diff --git a/lang/English/mail_templates/activate_email.tpl b/lang/English/mail_templates/activate_email.tpl new file mode 100644 index 0000000..f17066f --- /dev/null +++ b/lang/English/mail_templates/activate_email.tpl @@ -0,0 +1,12 @@ +Subject: Change email address requested + +Hello , + +You have requested to have a new email address assigned to your account in the discussion forum at . If you didn't request this or if you don't want to change your email address you should just ignore this message. Only if you visit the activation page below will your email address be changed. In order for the activation page to work, you must be logged in to the forum. + +To change your email address, please visit the following page: + + +-- + +(Do not reply to this message) diff --git a/lang/English/mail_templates/activate_password.tpl b/lang/English/mail_templates/activate_password.tpl new file mode 100644 index 0000000..33b2b3e --- /dev/null +++ b/lang/English/mail_templates/activate_password.tpl @@ -0,0 +1,14 @@ +Subject: New password requested + +Hello , + +You have requested to have a new password assigned to your account in the discussion forum at . If you didn't request this or if you don't want to change your password you should just ignore this message. Only if you visit the activation page below will your password be changed. + +Your new password is: + +To change your password, please visit the following page: + + +-- + +(Do not reply to this message) diff --git a/lang/English/mail_templates/form_email.tpl b/lang/English/mail_templates/form_email.tpl new file mode 100644 index 0000000..b862422 --- /dev/null +++ b/lang/English/mail_templates/form_email.tpl @@ -0,0 +1,13 @@ +Subject: + + from has sent you a message. You can reply to by replying to this email. + +The message reads as follows: +----------------------------------------------------------------------- + + + +----------------------------------------------------------------------- + +-- + diff --git a/lang/English/mail_templates/index.html b/lang/English/mail_templates/index.html new file mode 100644 index 0000000..89337b2 --- /dev/null +++ b/lang/English/mail_templates/index.html @@ -0,0 +1 @@ +.. diff --git a/lang/English/mail_templates/new_reply.tpl b/lang/English/mail_templates/new_reply.tpl new file mode 100644 index 0000000..e9dab0b --- /dev/null +++ b/lang/English/mail_templates/new_reply.tpl @@ -0,0 +1,11 @@ +Subject: Reply to topic: + + has replied to the topic to which you are subscribed. There may be more new replies, but this is the only notification you will receive until you visit the board again. + +The post is located at + +You can unsubscribe by going to + +-- + +(Do not reply to this message) diff --git a/lang/English/mail_templates/new_reply_full.tpl b/lang/English/mail_templates/new_reply_full.tpl new file mode 100644 index 0000000..7231145 --- /dev/null +++ b/lang/English/mail_templates/new_reply_full.tpl @@ -0,0 +1,18 @@ +Subject: Reply to topic: + + has replied to the topic to which you are subscribed. There may be more new replies, but this is the only notification you will receive until you visit the board again. + +The message reads as follows: +----------------------------------------------------------------------- + + + +----------------------------------------------------------------------- + +The post is located at + +You can unsubscribe by going to + +-- + +(Do not reply to this message) diff --git a/lang/English/mail_templates/welcome.tpl b/lang/English/mail_templates/welcome.tpl new file mode 100644 index 0000000..0110042 --- /dev/null +++ b/lang/English/mail_templates/welcome.tpl @@ -0,0 +1,12 @@ +Subject: Welcome to ! + +Thank you for registering in the forums at . Your account details are: + +Username: +Password: + +Login at to activate the account. + +-- + +(Do not reply to this message) diff --git a/lang/English/misc.php b/lang/English/misc.php new file mode 100644 index 0000000..9ccd4b2 --- /dev/null +++ b/lang/English/misc.php @@ -0,0 +1,90 @@ + 'All topics and forums have been marked as read. Redirecting …', +'Mark forum read redirect' => 'All topics in the specified forum have been marked as read. Redirecting …', + +// Send email +'Form email disabled' => 'The user you are trying to send an email to has disabled form email.', +'No email subject' => 'You must enter a subject.', +'No email message' => 'You must enter a message.', +'Too long email message' => 'Messages cannot be longer than 65535 characters (64 KB).', +'Email flood' => 'At least %s seconds have to pass between sent emails. Please wait a while and try sending again.', +'Email sent redirect' => 'Email sent. Redirecting …', +'Send email to' => 'Send email to', +'Email subject' => 'Subject', +'Email message' => 'Message', +'Email disclosure note' => 'Please note that by using this form, your email address will be disclosed to the recipient.', +'Write email' => 'Write and submit your email message', + +// Report +'No reason' => 'You must enter a reason.', +'Report flood' => 'At least %s seconds have to pass between reports. Please wait a while and try sending again.', +'Report redirect' => 'Post reported. Redirecting …', +'Report post' => 'Report post', +'Reason' => 'Reason', +'Reason desc' => 'Please enter a short reason why you are reporting this post', + +// Subscriptions +'Already subscribed' => 'You are already subscribed to this topic.', +'Subscribe redirect' => 'Your subscription has been added. Redirecting …', +'Not subscribed' => 'You are not subscribed to this topic.', +'Unsubscribe redirect' => 'Your subscription has been removed. Redirecting …', + +// General forum and topic moderation +'Moderate' => 'Moderate', +'Select' => 'Select', // the header of a column of checkboxes +'Move' => 'Move', +'Split' => 'Split', +'Delete' => 'Delete', +'Merge' => 'Merge', + +// Moderate forum +'Open' => 'Open', +'Close' => 'Close', +'Move topic' => 'Move topic', +'Move topics' => 'Move topics', +'Move legend' => 'Select destination of move', +'Move to' => 'Move to', +'Nowhere to move' => 'There are no forums into which you can move topics.', +'Leave redirect' => 'Leave redirect topic(s)', +'Move topic redirect' => 'Topic moved. Redirecting …', +'Move topics redirect' => 'Topics moved. Redirecting …', +'Confirm delete legend' => 'Please confirm deletion', +'Delete topics' => 'Delete topics', +'Delete topics comply' => 'Are you sure you want to delete the selected topics?', +'Delete topics redirect' => 'Topics deleted. Redirecting …', +'Open topic redirect' => 'Topic opened. Redirecting …', +'Open topics redirect' => 'Topics opened. Redirecting …', +'Close topic redirect' => 'Topic closed. Redirecting …', +'Close topics redirect' => 'Topics closed. Redirecting …', +'No topics selected' => 'You must select at least one topic for move/delete/open/close.', +'Not enough topics selected' => 'You must select at least two topics for merge.', +'Stick topic redirect' => 'Topic sticked. Redirecting …', +'Unstick topic redirect' => 'Topic unsticked. Redirecting …', +'Merge topics' => 'Merge topics', +'Merge topics redirect' => 'Topics merged. Redirecting …', +'Confirm merge legend' => 'Please confirm merge', +'New subject' => 'New subject', + +// Split multiple posts in topic +'Confirm split legend' => 'Please confirm split of selected posts.', +'Split posts' => 'Split posts', +'Split posts comply' => 'Are you sure you want to split the selected posts?', +'Split posts redirect' => 'Posts have been split. Redirecting …', + +// Delete multiple posts in topic +'Delete posts' => 'Delete posts', +'Cannot select first' => 'First post cannot be selected for split/delete.', +'Delete posts comply' => 'Are you sure you want to delete the selected posts?', +'Delete posts redirect' => 'Posts deleted. Redirecting …', +'No posts selected' => 'You must select at least one post for split/delete.', + +// Get host +'Host info 1' => 'The IP address is: %s', +'Host info 2' => 'The host name is: %s', +'Show more users' => 'Show more users for this IP', + +); diff --git a/lang/English/post.php b/lang/English/post.php new file mode 100644 index 0000000..5c8ea37 --- /dev/null +++ b/lang/English/post.php @@ -0,0 +1,36 @@ + 'Topics must contain a subject.', +'Too long subject' => 'Subjects cannot be longer than 70 characters.', +'No message' => 'You must enter a message.', +'Too long message' => 'Posts cannot be longer that 65535 characters (64 KB).', +'All caps subject' => 'Subjects cannot contain only capital letters.', +'All caps message' => 'Posts cannot contain only capital letters.', + +// Posting +'Post errors' => 'Post errors', +'Post errors info' => 'The following errors need to be corrected before the message can be posted:', +'Post preview' => 'Post preview', +'Guest name' => 'Name', // For guests (instead of Username) +'Post redirect' => 'Post entered. Redirecting …', +'Post a reply' => 'Post a reply', +'Post new topic' => 'Post new topic', +'Hide smilies' => 'Never show smilies as icons for this post', +'Subscribe' => 'Subscribe to this topic', +'Stay subscribed' => 'Stay subscribed to this topic', +'Topic review' => 'Topic review (newest first)', +'Flood start' => 'At least', +'flood end' => 'seconds have to pass between posts. Please wait a little while and try posting again.', +'Preview' => 'Preview', // submit button to preview message + +// Edit post +'Edit post legend' => 'Edit the post and submit changes', +'Silent edit' => 'Silent edit (don\'t display "Edited by ..." in topic view)', +'Edit post' => 'Edit post', +'Edit redirect' => 'Post updated. Redirecting …' + +); diff --git a/lang/English/prof_reg.php b/lang/English/prof_reg.php new file mode 100644 index 0000000..9a69b41 --- /dev/null +++ b/lang/English/prof_reg.php @@ -0,0 +1,81 @@ + 'Enter a valid email address', +'Email legend 2' => 'Enter and confirm a valid email address', +'Localisation legend' => 'Set your localisation options', +'Time zone' => 'Time zone', +'Time zone info' => 'For the forum to display times correctly you must select your local time zone. If Daylight Savings Time is in effect you should also check the option provided which will advance times by 1 hour.', +'DST' => 'Daylight Savings Time is in effect (advance time by 1 hour).', +'Time format' => 'Time format', +'Date format' => 'Date format', +'Default' => 'Default', +'Language' => 'Language', +'Email setting info' => 'Select whether you want your email address to be viewable to other users or not and if you want other users to be able to send you email via the forum (form email) or not.', +'Email setting 1' => 'Display your email address.', +'Email setting 2' => 'Hide your email address but allow form email.', +'Email setting 3' => 'Hide your email address and disallow form email.', +'Privacy options legend' => 'Set your privacy options', +'Confirm pass' => 'Confirm password', + +'Username too short' => 'Usernames must be at least 2 characters long. Please choose another (longer) username.', +'Username too long' => 'Usernames must not be more than 25 characters long. Please choose another (shorter) username.', +'Username guest' => 'The username guest is reserved. Please choose another username.', +'Username IP' => 'Usernames may not be in the form of an IP address. Please choose another username.', +'Username reserved chars' => 'Usernames may not contain all the characters \', " and [ or ] at once. Please choose another username.', +'Username BBCode' => 'Usernames may not contain any of the text formatting tags (BBCode) that the forum uses. Please choose another username.', +'Banned username' => 'The username you entered is banned in this forum. Please choose another username.', +'Pass too short' => 'Passwords must be at least 4 characters long. Please choose another (longer) password.', +'Pass not match' => 'Passwords do not match.', +'Banned email' => 'The email address you entered is banned in this forum. Please choose another email address.', +'Dupe email' => 'Someone else is already registered with that email address. Please choose another email address.', +'Sig too long' => 'Signatures cannot be longer than', +'characters' => 'characters', +'Sig too many lines' => 'Signatures cannot have more than', +'lines' => 'lines', +'Bad ICQ' => 'You entered an invalid ICQ UIN. Please go back and correct.', + +'UTC-12:00' => '(UTC-12:00) International Date Line West', +'UTC-11:00' => '(UTC-11:00) Niue, Samoa', +'UTC-10:00' => '(UTC-10:00) Hawaii-Aleutian, Cook Island', +'UTC-09:30' => '(UTC-09:30) Marquesas Islands', +'UTC-09:00' => '(UTC-09:00) Alaska, Gambier Island', +'UTC-08:30' => '(UTC-08:30) Pitcairn Islands', +'UTC-08:00' => '(UTC-08:00) Pacific', +'UTC-07:00' => '(UTC-07:00) Mountain', +'UTC-06:00' => '(UTC-06:00) Central', +'UTC-05:00' => '(UTC-05:00) Eastern', +'UTC-04:00' => '(UTC-04:00) Atlantic', +'UTC-03:30' => '(UTC-03:30) Newfoundland', +'UTC-03:00' => '(UTC-03:00) Amazon, Central Greenland', +'UTC-02:00' => '(UTC-02:00) Mid-Atlantic', +'UTC-01:00' => '(UTC-01:00) Azores, Cape Verde, Eastern Greenland', +'UTC' => '(UTC) Western European, Greenwich', +'UTC+01:00' => '(UTC+01:00) Central European, West African', +'UTC+02:00' => '(UTC+02:00) Eastern European, Central African', +'UTC+03:00' => '(UTC+03:00) Moscow, Eastern African', +'UTC+03:30' => '(UTC+03:30) Iran', +'UTC+04:00' => '(UTC+04:00) Gulf, Samara', +'UTC+04:30' => '(UTC+04:30) Afghanistan', +'UTC+05:00' => '(UTC+05:00) Pakistan, Yekaterinburg', +'UTC+05:30' => '(UTC+05:30) India, Sri Lanka', +'UTC+05:45' => '(UTC+05:45) Nepal', +'UTC+06:00' => '(UTC+06:00) Bangladesh, Bhutan, Novosibirsk', +'UTC+06:30' => '(UTC+06:30) Cocos Islands, Myanmar', +'UTC+07:00' => '(UTC+07:00) Indochina, Krasnoyarsk', +'UTC+08:00' => '(UTC+08:00) Greater China, Australian Western, Irkutsk', +'UTC+08:45' => '(UTC+08:45) Southeastern Western Australia', +'UTC+09:00' => '(UTC+09:00) Japan, Korea, Chita', +'UTC+09:30' => '(UTC+09:30) Australian Central', +'UTC+10:00' => '(UTC+10:00) Australian Eastern, Vladivostok', +'UTC+10:30' => '(UTC+10:30) Lord Howe', +'UTC+11:00' => '(UTC+11:00) Solomon Island, Magadan', +'UTC+11:30' => '(UTC+11:30) Norfolk Island', +'UTC+12:00' => '(UTC+12:00) New Zealand, Fiji, Kamchatka', +'UTC+12:45' => '(UTC+12:45) Chatham Islands', +'UTC+13:00' => '(UTC+13:00) Tonga, Phoenix Islands', +'UTC+14:00' => '(UTC+14:00) Line Islands' + +); diff --git a/lang/English/profile.php b/lang/English/profile.php new file mode 100644 index 0000000..ef6a98c --- /dev/null +++ b/lang/English/profile.php @@ -0,0 +1,140 @@ + 'Profile menu', +'Section essentials' => 'Essentials', +'Section personal' => 'Personal', +'Section messaging' => 'Messaging', +'Section personality' => 'Personality', +'Section display' => 'Display', +'Section privacy' => 'Privacy', +'Section admin' => 'Administration', + +// Miscellaneous +'Username and pass legend' => 'Enter your username and password', +'Personal details legend' => 'Enter your personal details', +'Contact details legend' => 'Enter your messaging details', +'User activity' => 'User activity', +'Paginate info' => 'Enter the number of topics and posts you wish to view on each page.', + +// Password stuff +'Pass key bad' => 'The specified password activation key was incorrect or has expired. Please re-request a new password. If that fails, contact the forum administrator at', +'Pass updated' => 'Your password has been updated. You can now login with your new password.', +'Pass updated redirect' => 'Password updated. Redirecting …', +'Wrong pass' => 'Wrong old password.', +'Change pass' => 'Change password', +'Change pass legend' => 'Enter and confirm your new password', +'Old pass' => 'Old password', +'New pass' => 'New password', +'Confirm new pass' => 'Confirm new password', +'Pass info' => 'Passwords must be at least 4 characters long. Passwords are case sensitive.', + +// Email stuff +'Email key bad' => 'The specified email activation key was incorrect or has expired. Please re-request change of email address. If that fails, contact the forum administrator at', +'Email updated' => 'Your email address has been updated.', +'Activate email sent' => 'An email has been sent to the specified address with instructions on how to activate the new email address. If it doesn\'t arrive you can contact the forum administrator at', +'Email legend' => 'Enter your new email address', +'Email instructions' => 'An email will be sent to your new address with an activation link. You must click the link in the email you receive to activate the new address.', +'Change email' => 'Change email address', +'New email' => 'New email', + +// Avatar upload stuff +'Avatars disabled' => 'The administrator has disabled avatar support.', +'Too large ini' => 'The selected file was too large to upload. The server didn\'t allow the upload.', +'Partial upload' => 'The selected file was only partially uploaded. Please try again.', +'No tmp directory' => 'PHP was unable to save the uploaded file to a temporary location.', +'No file' => 'You did not select a file for upload.', +'Bad type' => 'The file you tried to upload is not of an allowed type. Allowed types are gif, jpeg and png.', +'Too wide or high' => 'The file you tried to upload is wider and/or higher than the maximum allowed', +'Too large' => 'The file you tried to upload is larger than the maximum allowed', +'pixels' => 'pixels', +'bytes' => 'bytes', +'Move failed' => 'The server was unable to save the uploaded file. Please contact the forum administrator at', +'Unknown failure' => 'An unknown error occurred. Please try again.', +'Avatar upload redirect' => 'Avatar uploaded. Redirecting …', +'Avatar deleted redirect' => 'Avatar deleted. Redirecting …', +'Avatar desc' => 'An avatar is a small image that will be displayed under your username in your posts. It must not be any bigger than', +'Upload avatar' => 'Upload avatar', +'Upload avatar legend' => 'Enter an avatar file to upload', +'Delete avatar' => 'Delete avatar', // only for admins +'File' => 'File', +'Upload' => 'Upload', // submit button + +// Form validation stuff +'Forbidden title' => 'The title you entered contains a forbidden word. You must choose a different title.', +'Profile redirect' => 'Profile updated. Redirecting …', + +// Profile display stuff +'Users profile' => '%s\'s profile', +'Unknown' => '(Unknown)', // This is displayed when a user hasn't filled out profile field (e.g. Location) +'Private' => '(Private)', // This is displayed when a user does not want to receive emails +'No avatar' => '(No avatar)', +'Username info' => 'Username: %s', +'Email info' => 'Email: %s', +'Posts info' => 'Posts: %s', +'Registered info' => 'Registered: %s', +'Last post info' => 'Last post: %s', +'Show posts' => 'Show all posts', +'Realname' => 'Real name', +'Location' => 'Location', +'Website' => 'Website', +'Jabber' => 'Jabber', +'ICQ' => 'ICQ', +'MSN' => 'MSN Messenger', +'AOL IM' => 'AOL IM', +'Yahoo' => 'Yahoo! Messenger', +'Avatar' => 'Avatar', +'Signature' => 'Signature', +'Sig max size' => 'Max length: %s characters / Max lines: %s', +'Avatar legend' => 'Set your avatar display options', +'Avatar info' => 'An avatar is a small image that will be displayed with all your posts. You can upload an avatar by clicking the link below.', +'Change avatar' => 'Change avatar', +'Signature legend' => 'Compose your signature', +'Signature info' => 'A signature is a small piece of text that is attached to your posts. In it, you can enter just about anything you like. Perhaps you would like to enter your favourite quote or your star sign. It\'s up to you! In your signature you can use BBCode if it is allowed in this particular forum. You can see the features that are allowed/enabled listed below whenever you edit your signature.', +'Sig preview' => 'Current signature preview:', +'No sig' => 'No signature currently stored in profile.', +'Signature quote/code/list/h' => 'The quote, code, list, and heading BBCodes are not allowed in signatures.', +'Topics per page' => 'Topics', +'Posts per page' => 'Posts', +'Leave blank' => 'Leave blank to use forum default.', +'Subscription legend' => 'Set your subscription options', +'Notify full' => 'Include a plain text version of new posts in subscription notification emails.', +'Auto notify full' => 'Automatically subscribe to every topic you post in.', +'Show smilies' => 'Show smilies as graphic icons.', +'Show images' => 'Show images in posts.', +'Show images sigs' => 'Show images in user signatures.', +'Show avatars' => 'Show user avatars in posts.', +'Show sigs' => 'Show user signatures.', +'Style legend' => 'Select your preferred style', +'Styles' => 'Styles', +'Admin note' => 'Admin note', +'Pagination legend' => 'Enter your pagination options', +'Post display legend' => 'Set your options for viewing posts', +'Post display info' => 'If you are on a slow connection, disabling these options, particularly showing images in posts and signatures, will make pages load faster.', +'Instructions' => 'When you update your profile, you will be redirected back to this page.', + +// Administration stuff +'Group membership legend' => 'Choose user group', +'Save' => 'Save', +'Set mods legend' => 'Set moderator access', +'Moderator in info' => 'Choose which forums this user should be allowed to moderate. Note: This only applies to moderators. Administrators always have full permissions in all forums.', +'Update forums' => 'Update forums', +'Delete ban legend' => 'Delete (administrators only) or ban user', +'Delete user' => 'Delete user', +'Ban user' => 'Ban user', +'Confirm delete legend' => 'Important: read before deleting user', +'Confirm delete user' => 'Confirm delete user', +'Confirmation info' => 'Please confirm that you want to delete the user', // the username will be appended to this string +'Delete warning' => 'Warning! Deleted users and/or posts cannot be restored. If you choose not to delete the posts made by this user, the posts can only be deleted manually at a later time.', +'Delete posts' => 'Delete any posts and topics this user has made.', +'Delete' => 'Delete', // submit button (confirm user delete) +'User delete redirect' => 'User deleted. Redirecting …', +'Group membership redirect' => 'Group membership saved. Redirecting …', +'Update forums redirect' => 'Forum moderator rights updated. Redirecting …', +'Ban redirect' => 'Redirecting …', +'No delete admin message' => 'Administrators cannot be deleted. In order to delete this user, you must first move him/her to a different user group.', + +); diff --git a/lang/English/register.php b/lang/English/register.php new file mode 100644 index 0000000..c3e24df --- /dev/null +++ b/lang/English/register.php @@ -0,0 +1,37 @@ + 'This forum is not accepting new registrations.', +'Reg cancel redirect' => 'Registration cancelled. Redirecting …', +'Forum rules' => 'Forum rules', +'Rules legend' => 'You must agree to the following in order to register', +'Registration flood' => 'A new user was registered with the same IP address as you within the last hour. To prevent registration flooding, at least an hour has to pass between registrations from the same IP. Sorry for the inconvenience.', +'Agree' => 'Agree', +'Cancel' => 'Cancel', +'Register' => 'Register', + +// Form validation stuff (some of these are also used in post.php) +'Registration errors' => 'Registration errors', +'Registration errors info' => 'The following errors need to be corrected before you can register:', +'Username censor' => 'The username you entered contains one or more censored words. Please choose a different username.', +'Username dupe 1' => 'Someone is already registered with the username', +'Username dupe 2' => 'The username you entered is too similar. The username must differ from that by at least one alphanumerical character (a-z or 0-9). Please choose a different username.', +'Email not match' => 'Email addresses do not match.', + +// Registration email stuff +'Reg email' => 'Thank you for registering. Your password has been sent to the specified address. If it doesn\'t arrive you can contact the forum administrator at', +'Reg complete' => 'Registration complete. Logging in and redirecting …', + +// Register info +'Desc 1' => 'Registration will grant you access to a number of features and capabilities otherwise unavailable. These functions include the ability to edit and delete posts, design your own signature that accompanies your posts and much more. If you have any questions regarding this forum you should ask an administrator.', +'Desc 2' => 'Below is a form you must fill out in order to register. Once you are registered you should visit your profile and review the different settings you can change. The fields below only make up a small part of all the settings you can alter in your profile.', +'Username legend' => 'Please enter a username between 2 and 25 characters long', +'Pass legend' => 'Please enter and confirm your chosen password', +'Pass info' => 'Passwords must be at least 4 characters long. Passwords are case sensitive.', +'Email info' => 'You must enter a valid email address as your randomly generated password will be sent to that address.', +'Confirm email' => 'Confirm email address', + +); diff --git a/lang/English/search.php b/lang/English/search.php new file mode 100644 index 0000000..d6a5081 --- /dev/null +++ b/lang/English/search.php @@ -0,0 +1,49 @@ + 'User search', +'No search permission' => 'You do not have permission to use the search feature.', +'Search flood' => 'At least %s seconds have to pass between searches. Please wait a while and try searching again.', +'Search' => 'Search', +'Search criteria legend' => 'Enter your search criteria', +'Search info' => 'To search by keyword, enter a term or terms to search for. Separate terms with spaces. Use AND, OR and NOT to refine your search. To search by author enter the username of the author whose posts you wish to search for. Use wildcard character * for partial matches.', +'Keyword search' => 'Keyword search', +'Author search' => 'Author search', +'Search in legend' => 'Select where to search', +'Search in info' => 'Choose in which forum you would like to search and if you want to search in topic subjects, message text or both.', +'Forum search' => 'Forum', +'All forums' => 'All forums', +'Search in' => 'Search in', +'Message and subject' => 'Message text and topic subject', +'Message only' => 'Message text only', +'Topic only' => 'Topic subject only', +'Sort by' => 'Sort by', +'Sort order' => 'Sort order', +'Search results legend' => 'Select how to view search results', +'Search results info' => 'You can choose how you wish to sort and show your results.', +'Sort by post time' => 'Post time', +'Sort by author' => 'Author', +'Sort by subject' => 'Subject', +'Sort by forum' => 'Forum', +'Ascending' => 'Ascending', +'Descending' => 'Descending', +'Show as' => 'Show results as', +'Show as topics' => 'Topics', +'Show as posts' => 'Posts', + +// Results +'Search results' => 'Search results', +'No terms' => 'You have to enter at least one keyword and/or an author to search for.', +'No hits' => 'Your search returned no hits.', +'No user posts' => 'There are no posts by this user in this forum.', +'No subscriptions' => 'You are currently not subscribed to any topics.', +'No new posts' => 'There are no topics with new posts since your last visit.', +'No recent posts' => 'No new posts have been made within the last 24 hours.', +'No unanswered' => 'There are no unanswered posts in this forum.', +'Go to post' => 'Go to post', +'Go to topic' => 'Go to topic' + +); diff --git a/lang/English/stopwords.txt b/lang/English/stopwords.txt new file mode 100644 index 0000000..907a260 --- /dev/null +++ b/lang/English/stopwords.txt @@ -0,0 +1,175 @@ +about +after +ago +all +almost +along +also +any +anybody +anywhere +are +arent +aren't +around +ask +been +before +being +between +but +came +can +cant +can't +come +could +couldnt +couldn't +did +didnt +didn't +does +doesnt +doesn't +dont +don't +each +either +else +even +every +everybody +everyone +find +for +from +get +going +gone +got +had +has +have +havent +haven't +having +her +here +hers +him +his +how +ill +i'll +i'm +into +isnt +isn't +itll +it'll +its +it's +ive +i've +just +know +less +like +make +many +may +more +most +much +must +near +never +none +nothing +now +off +often +once +one +only +other +our +ours +our's +out +over +please +rather +really +said +see +she +should +small +some +something +sometime +somewhere +take +than +thank +thanks +that +thats +that's +the +their +theirs +them +then +there +these +they +thing +think +this +those +though +through +thus +too +true +two +under +until +upon +use +very +want +was +way +well +were +what +when +where +which +who +whom +whose +why +will +with +within +without +would +yes +yet +you +your +youre +you're +yours +http +https +ftp +www +com +net +org diff --git a/lang/English/topic.php b/lang/English/topic.php new file mode 100644 index 0000000..1f74dda --- /dev/null +++ b/lang/English/topic.php @@ -0,0 +1,31 @@ + 'Post reply', +'Topic closed' => 'Topic closed', +'From' => 'From:', // User location +'IP address logged' => 'IP address logged', +'Note' => 'Note:', // Admin note +'Posts' => 'Posts:', +'Registered' => 'Registered:', +'Replies' => 'Replies:', +'Website' => 'Website', +'Guest' => 'Guest', +'Online' => 'Online', +'Offline' => 'Offline', +'Last edit' => 'Last edited by', +'Report' => 'Report', +'Delete' => 'Delete', +'Edit' => 'Edit', +'Quote' => 'Quote', +'Is subscribed' => 'You are currently subscribed to this topic', +'Unsubscribe' => 'Unsubscribe', +'Subscribe' => 'Subscribe to this topic', +'Quick post' => 'Quick post', +'Mod controls' => 'Moderator controls', +'New icon' => 'New post', +'Re' => 'Re:' + +); diff --git a/lang/English/userlist.php b/lang/English/userlist.php new file mode 100644 index 0000000..0853d25 --- /dev/null +++ b/lang/English/userlist.php @@ -0,0 +1,13 @@ + 'Find and sort users', +'User search info' => 'Enter a username to search for and/or a user group to filter by. The username field can be left blank. Use the wildcard character * for partial matches.', +'User sort info' => 'Sort users by name, date registered or number of posts and in ascending/descending order.', +'User group' => 'User group', +'No of posts' => 'Number of posts', +'All users' => 'All' + +); diff --git a/lang/index.html b/lang/index.html new file mode 100644 index 0000000..89337b2 --- /dev/null +++ b/lang/index.html @@ -0,0 +1 @@ +.. diff --git a/login.php b/login.php new file mode 100644 index 0000000..0f899c4 --- /dev/null +++ b/login.php @@ -0,0 +1,263 @@ +escape($form_username).'\'' : 'LOWER(username)=LOWER(\''.$db->escape($form_username).'\')'; + + $result = $db->query('SELECT * FROM '.$db->prefix.'users WHERE '.$username_sql) or error('Unable to fetch user info', __FILE__, __LINE__, $db->error()); + $cur_user = $db->fetch_assoc($result); + + $authorized = false; + + if (!empty($cur_user['password'])) + { + $form_password_hash = pun_hash($form_password); // Will result in a SHA-1 hash + + // If there is a salt in the database we have upgraded from 1.3-legacy though havent yet logged in + if (!empty($cur_user['salt'])) + { + if (sha1($cur_user['salt'].sha1($form_password)) == $cur_user['password']) // 1.3 used sha1(salt.sha1(pass)) + { + $authorized = true; + + $db->query('UPDATE '.$db->prefix.'users SET password=\''.$form_password_hash.'\', salt=NULL WHERE id='.$cur_user['id']) or error('Unable to update user password', __FILE__, __LINE__, $db->error()); + } + } + // If the length isn't 40 then the password isn't using sha1, so it must be md5 from 1.2 + else if (strlen($cur_user['password']) != 40) + { + if (md5($form_password) == $cur_user['password']) + { + $authorized = true; + + $db->query('UPDATE '.$db->prefix.'users SET password=\''.$form_password_hash.'\' WHERE id='.$cur_user['id']) or error('Unable to update user password', __FILE__, __LINE__, $db->error()); + } + } + // Otherwise we should have a normal sha1 password + else + $authorized = ($cur_user['password'] == $form_password_hash); + } + + if (!$authorized) + message($lang_login['Wrong user/pass'].' '.$lang_login['Forgotten pass'].''); + + // Update the status if this is the first time the user logged in + if ($cur_user['group_id'] == PUN_UNVERIFIED) + $db->query('UPDATE '.$db->prefix.'users SET group_id='.$pun_config['o_default_user_group'].' WHERE id='.$cur_user['id']) or error('Unable to update user status', __FILE__, __LINE__, $db->error()); + + // Remove this users guest entry from the online list + $db->query('DELETE FROM '.$db->prefix.'online WHERE ident=\''.$db->escape(get_remote_address()).'\'') or error('Unable to delete from online list', __FILE__, __LINE__, $db->error()); + + $expire = ($save_pass == '1') ? time() + 1209600 : time() + $pun_config['o_timeout_visit']; + pun_setcookie($cur_user['id'], $form_password_hash, $expire); + + // Reset tracked topics + set_tracked_topics(null); + + redirect(htmlspecialchars($_POST['redirect_url']), $lang_login['Login redirect']); +} + + +else if ($action == 'out') +{ + if ($pun_user['is_guest'] || !isset($_GET['id']) || $_GET['id'] != $pun_user['id'] || !isset($_GET['csrf_token']) || $_GET['csrf_token'] != pun_hash($pun_user['id'].pun_hash(get_remote_address()))) + { + header('Location: index.php'); + exit; + } + + // Remove user from "users online" list + $db->query('DELETE FROM '.$db->prefix.'online WHERE user_id='.$pun_user['id']) or error('Unable to delete from online list', __FILE__, __LINE__, $db->error()); + + // Update last_visit (make sure there's something to update it with) + if (isset($pun_user['logged'])) + $db->query('UPDATE '.$db->prefix.'users SET last_visit='.$pun_user['logged'].' WHERE id='.$pun_user['id']) or error('Unable to update user visit data', __FILE__, __LINE__, $db->error()); + + pun_setcookie(1, md5(uniqid(rand(), true)), time() + 31536000); + + redirect('index.php', $lang_login['Logout redirect']); +} + + +else if ($action == 'forget' || $action == 'forget_2') +{ + if (!$pun_user['is_guest']) + header('Location: index.php'); + + if (isset($_POST['form_sent'])) + { + // Start with a clean slate + $errors = array(); + + require PUN_ROOT.'include/email.php'; + + // Validate the email address + $email = strtolower(trim($_POST['req_email'])); + if (!is_valid_email($email)) + $errors[] = $lang_common['Invalid email']; + + // Did everything go according to plan? + if (empty($errors)) + { + $result = $db->query('SELECT id, username, last_email_sent FROM '.$db->prefix.'users WHERE email=\''.$db->escape($email).'\'') or error('Unable to fetch user info', __FILE__, __LINE__, $db->error()); + + if ($db->num_rows($result)) + { + // Load the "activate password" template + $mail_tpl = trim(file_get_contents(PUN_ROOT.'lang/'.$pun_user['language'].'/mail_templates/activate_password.tpl')); + + // The first row contains the subject + $first_crlf = strpos($mail_tpl, "\n"); + $mail_subject = trim(substr($mail_tpl, 8, $first_crlf-8)); + $mail_message = trim(substr($mail_tpl, $first_crlf)); + + // Do the generic replacements first (they apply to all emails sent out here) + $mail_message = str_replace('', $pun_config['o_base_url'].'/', $mail_message); + $mail_message = str_replace('', $pun_config['o_board_title'].' '.$lang_common['Mailer'], $mail_message); + + // Loop through users we found + while ($cur_hit = $db->fetch_assoc($result)) + { + if ($cur_hit['last_email_sent'] != '' && (time() - $cur_hit['last_email_sent']) < 3600 && (time() - $cur_hit['last_email_sent']) >= 0) + message($lang_login['Email flood'], true); + + // Generate a new password and a new password activation code + $new_password = random_pass(8); + $new_password_key = random_pass(8); + + $db->query('UPDATE '.$db->prefix.'users SET activate_string=\''.pun_hash($new_password).'\', activate_key=\''.$new_password_key.'\', last_email_sent = '.time().' WHERE id='.$cur_hit['id']) or error('Unable to update activation data', __FILE__, __LINE__, $db->error()); + + // Do the user specific replacements to the template + $cur_mail_message = str_replace('', $cur_hit['username'], $mail_message); + $cur_mail_message = str_replace('', $pun_config['o_base_url'].'/profile.php?id='.$cur_hit['id'].'&action=change_pass&key='.$new_password_key, $cur_mail_message); + $cur_mail_message = str_replace('', $new_password, $cur_mail_message); + + pun_mail($email, $mail_subject, $cur_mail_message); + } + + message($lang_login['Forget mail'].' '.$pun_config['o_admin_email'].'.', true); + } + else + $errors[] = $lang_login['No email match'].' '.htmlspecialchars($email).'.'; + } + } + + $page_title = array(pun_htmlspecialchars($pun_config['o_board_title']), $lang_login['Request pass']); + $required_fields = array('req_email' => $lang_common['Email']); + $focus_element = array('request_pass', 'req_email'); + define ('PUN_ACTIVE_PAGE', 'login'); + require PUN_ROOT.'header.php'; + +// If there are errors, we display them +if (!empty($errors)) +{ + +?> +
    +

    +
    +
    +

    +
      +'.$cur_error.''."\n"; +?> +
    +
    +
    +
    + + +
    +

    +
    +
    +
    +
    + +
    + + +

    +
    +
    +
    +

    +
    +
    +
    + $lang_common['Username'], 'req_password' => $lang_common['Password']); +$focus_element = array('login', 'req_username'); +define('PUN_ACTIVE_PAGE', 'login'); +require PUN_ROOT.'header.php'; + +?> +
    +

    +
    +
    +
    +
    + +
    + + + + + +
    + +
    + +

    +

    +
    +
    +
    +

    +
    +
    +
    + +
    +

    +
    +
    +
    +
    +
    +
    +query('UPDATE '.$db->prefix.'users SET last_visit='.$pun_user['logged'].' WHERE id='.$pun_user['id']) or error('Unable to update user last visit data', __FILE__, __LINE__, $db->error()); + + // Reset tracked topics + set_tracked_topics(null); + + redirect('index.php', $lang_misc['Mark read redirect']); +} + + +// Mark the topics/posts in a forum as read? +else if ($action == 'markforumread') +{ + if ($pun_user['is_guest']) + message($lang_common['No permission']); + + $fid = isset($_GET['fid']) ? intval($_GET['fid']) : 0; + if ($fid < 1) + message($lang_common['Bad request']); + + $tracked_topics = get_tracked_topics(); + $tracked_topics['forums'][$fid] = time(); + set_tracked_topics($tracked_topics); + + redirect('viewforum.php?id='.$fid, $lang_misc['Mark forum read redirect']); +} + + +else if (isset($_GET['email'])) +{ + if ($pun_user['is_guest'] || $pun_user['g_send_email'] == '0') + message($lang_common['No permission']); + + $recipient_id = intval($_GET['email']); + if ($recipient_id < 2) + message($lang_common['Bad request']); + + $result = $db->query('SELECT username, email, email_setting FROM '.$db->prefix.'users WHERE id='.$recipient_id) or error('Unable to fetch user info', __FILE__, __LINE__, $db->error()); + if (!$db->num_rows($result)) + message($lang_common['Bad request']); + + list($recipient, $recipient_email, $email_setting) = $db->fetch_row($result); + + if ($email_setting == 2 && !$pun_user['is_admmod']) + message($lang_misc['Form email disabled']); + + + if (isset($_POST['form_sent'])) + { + // Clean up message and subject from POST + $subject = pun_trim($_POST['req_subject']); + $message = pun_trim($_POST['req_message']); + + if ($subject == '') + message($lang_misc['No email subject']); + else if ($message == '') + message($lang_misc['No email message']); + else if (pun_strlen($message) > PUN_MAX_POSTSIZE) + message($lang_misc['Too long email message']); + + if ($pun_user['last_email_sent'] != '' && (time() - $pun_user['last_email_sent']) < $pun_user['g_email_flood'] && (time() - $pun_user['last_email_sent']) >= 0) + message(sprintf($lang_misc['Email flood'], $pun_user['g_email_flood'])); + + // Load the "form email" template + $mail_tpl = trim(file_get_contents(PUN_ROOT.'lang/'.$pun_user['language'].'/mail_templates/form_email.tpl')); + + // The first row contains the subject + $first_crlf = strpos($mail_tpl, "\n"); + $mail_subject = pun_trim(substr($mail_tpl, 8, $first_crlf-8)); + $mail_message = pun_trim(substr($mail_tpl, $first_crlf)); + + $mail_subject = str_replace('', $subject, $mail_subject); + $mail_message = str_replace('', $pun_user['username'], $mail_message); + $mail_message = str_replace('', $pun_config['o_board_title'], $mail_message); + $mail_message = str_replace('', $message, $mail_message); + $mail_message = str_replace('', $pun_config['o_board_title'].' '.$lang_common['Mailer'], $mail_message); + + require_once PUN_ROOT.'include/email.php'; + + pun_mail($recipient_email, $mail_subject, $mail_message, $pun_user['email'], $pun_user['username']); + + $db->query('UPDATE '.$db->prefix.'users SET last_email_sent='.time().' WHERE id='.$pun_user['id']) or error('Unable to update user', __FILE__, __LINE__, $db->error()); + + redirect(htmlspecialchars($_POST['redirect_url']), $lang_misc['Email sent redirect']); + } + + + // Try to determine if the data in HTTP_REFERER is valid (if not, we redirect to the users profile after the email is sent) + $redirect_url = (isset($_SERVER['HTTP_REFERER']) && preg_match('#^'.preg_quote($pun_config['o_base_url']).'/(.*?)\.php#i', $_SERVER['HTTP_REFERER'])) ? htmlspecialchars($_SERVER['HTTP_REFERER']) : 'index.php'; + + $page_title = array(pun_htmlspecialchars($pun_config['o_board_title']), $lang_misc['Send email to'].' '.pun_htmlspecialchars($recipient)); + $required_fields = array('req_subject' => $lang_misc['Email subject'], 'req_message' => $lang_misc['Email message']); + $focus_element = array('email', 'req_subject'); + define('PUN_ACTIVE_PAGE', 'index'); + require PUN_ROOT.'header.php'; + +?> +
    +

    +
    +
    +
    +
    + +
    + + + + +

    +
    +
    +
    +

    +
    +
    +
    += 0) + message(sprintf($lang_misc['Report flood'], $pun_user['g_email_flood'])); + + // Get the topic ID + $result = $db->query('SELECT topic_id FROM '.$db->prefix.'posts WHERE id='.$post_id) or error('Unable to fetch post info', __FILE__, __LINE__, $db->error()); + if (!$db->num_rows($result)) + message($lang_common['Bad request']); + + $topic_id = $db->result($result); + + // Get the subject and forum ID + $result = $db->query('SELECT subject, forum_id FROM '.$db->prefix.'topics WHERE id='.$topic_id) or error('Unable to fetch topic info', __FILE__, __LINE__, $db->error()); + if (!$db->num_rows($result)) + message($lang_common['Bad request']); + + list($subject, $forum_id) = $db->fetch_row($result); + + // Should we use the internal report handling? + if ($pun_config['o_report_method'] == '0' || $pun_config['o_report_method'] == '2') + $db->query('INSERT INTO '.$db->prefix.'reports (post_id, topic_id, forum_id, reported_by, created, message) VALUES('.$post_id.', '.$topic_id.', '.$forum_id.', '.$pun_user['id'].', '.time().', \''.$db->escape($reason).'\')' ) or error('Unable to create report', __FILE__, __LINE__, $db->error()); + + // Should we email the report? + if ($pun_config['o_report_method'] == '1' || $pun_config['o_report_method'] == '2') + { + // We send it to the complete mailing-list in one swoop + if ($pun_config['o_mailing_list'] != '') + { + $mail_subject = sprintf($lang_common['Report notification'], $forum_id, $subject); + $mail_message = sprintf($lang_common['Report message 1'], $pun_user['username'], $pun_config['o_base_url'].'/viewtopic.php?pid='.$post_id.'#p'.$post_id)."\n"; + $mail_message .= sprintf($lang_common['Report message 2'], $reason)."\n"; + $mail_message .= "\n".'--'."\n".$lang_common['Email signature']; + + require PUN_ROOT.'include/email.php'; + + pun_mail($pun_config['o_mailing_list'], $mail_subject, $mail_message); + } + } + + $db->query('UPDATE '.$db->prefix.'users SET last_email_sent='.time().' WHERE id='.$pun_user['id']) or error('Unable to update user', __FILE__, __LINE__, $db->error()); + + redirect('viewtopic.php?pid='.$post_id.'#p'.$post_id, $lang_misc['Report redirect']); + } + + // Fetch some info about the post, the topic and the forum + $result = $db->query('SELECT f.id AS fid, f.forum_name, t.id AS tid, t.subject FROM '.$db->prefix.'posts AS p INNER JOIN '.$db->prefix.'topics AS t ON t.id=p.topic_id INNER JOIN '.$db->prefix.'forums AS f ON f.id=t.forum_id LEFT JOIN '.$db->prefix.'forum_perms AS fp ON (fp.forum_id=f.id AND fp.group_id='.$pun_user['g_id'].') WHERE (fp.read_forum IS NULL OR fp.read_forum=1) AND p.id='.$post_id) or error('Unable to fetch post info', __FILE__, __LINE__, $db->error()); + if (!$db->num_rows($result)) + message($lang_common['Bad request']); + + $cur_post = $db->fetch_assoc($result); + + if ($pun_config['o_censoring'] == '1') + $cur_post['subject'] = censor_words($cur_post['subject']); + + $page_title = array(pun_htmlspecialchars($pun_config['o_board_title']), $lang_misc['Report post']); + $required_fields = array('req_reason' => $lang_misc['Reason']); + $focus_element = array('report', 'req_reason'); + define('PUN_ACTIVE_PAGE', 'index'); + require PUN_ROOT.'header.php'; + +?> +
    +
    +
      +
    • +
    • » 
    • +
    • » 
    • +
    • » 
    • +
    +
    +
    + +
    +

    +
    +
    +
    +
    + +
    + + +
    +
    +
    +

    +
    +
    +
    +query('SELECT 1 FROM '.$db->prefix.'topics AS t LEFT JOIN '.$db->prefix.'forum_perms AS fp ON (fp.forum_id=t.forum_id AND fp.group_id='.$pun_user['g_id'].') WHERE (fp.read_forum IS NULL OR fp.read_forum=1) AND t.id='.$topic_id.' AND t.moved_to IS NULL') or error('Unable to fetch topic info', __FILE__, __LINE__, $db->error()); + if (!$db->num_rows($result)) + message($lang_common['Bad request']); + + $result = $db->query('SELECT 1 FROM '.$db->prefix.'subscriptions WHERE user_id='.$pun_user['id'].' AND topic_id='.$topic_id) or error('Unable to fetch subscription info', __FILE__, __LINE__, $db->error()); + if ($db->num_rows($result)) + message($lang_misc['Already subscribed']); + + $db->query('INSERT INTO '.$db->prefix.'subscriptions (user_id, topic_id) VALUES('.$pun_user['id'].' ,'.$topic_id.')') or error('Unable to add subscription', __FILE__, __LINE__, $db->error()); + + redirect('viewtopic.php?id='.$topic_id, $lang_misc['Subscribe redirect']); +} + + +else if (isset($_GET['unsubscribe'])) +{ + if ($pun_user['is_guest'] || $pun_config['o_subscriptions'] != '1') + message($lang_common['No permission']); + + $topic_id = intval($_GET['unsubscribe']); + if ($topic_id < 1) + message($lang_common['Bad request']); + + $result = $db->query('SELECT 1 FROM '.$db->prefix.'subscriptions WHERE user_id='.$pun_user['id'].' AND topic_id='.$topic_id) or error('Unable to fetch subscription info', __FILE__, __LINE__, $db->error()); + if (!$db->num_rows($result)) + message($lang_misc['Not subscribed']); + + $db->query('DELETE FROM '.$db->prefix.'subscriptions WHERE user_id='.$pun_user['id'].' AND topic_id='.$topic_id) or error('Unable to remove subscription', __FILE__, __LINE__, $db->error()); + + redirect('viewtopic.php?id='.$topic_id, $lang_misc['Unsubscribe redirect']); +} + + +else + message($lang_common['Bad request']); diff --git a/moderate.php b/moderate.php new file mode 100644 index 0000000..82f5ae1 --- /dev/null +++ b/moderate.php @@ -0,0 +1,915 @@ +query('SELECT poster_ip FROM '.$db->prefix.'posts WHERE id='.$get_host) or error('Unable to fetch post IP address', __FILE__, __LINE__, $db->error()); + if (!$db->num_rows($result)) + message($lang_common['Bad request']); + + $ip = $db->result($result); + } + + // Load the misc.php language file + require PUN_ROOT.'lang/'.$pun_user['language'].'/misc.php'; + + message(sprintf($lang_misc['Host info 1'], $ip).'
    '.sprintf($lang_misc['Host info 2'], @gethostbyaddr($ip)).'

    '.$lang_misc['Show more users'].''); +} + + +// All other functions require moderator/admin access +$fid = isset($_GET['fid']) ? intval($_GET['fid']) : 0; +if ($fid < 1) + message($lang_common['Bad request']); + +$result = $db->query('SELECT moderators FROM '.$db->prefix.'forums WHERE id='.$fid) or error('Unable to fetch forum info', __FILE__, __LINE__, $db->error()); + +$moderators = $db->result($result); +$mods_array = ($moderators != '') ? unserialize($moderators) : array(); + +if ($pun_user['g_id'] != PUN_ADMIN && ($pun_user['g_moderator'] == '0' || !array_key_exists($pun_user['username'], $mods_array))) + message($lang_common['No permission']); + +// Get topic/forum tracking data +if (!$pun_user['is_guest']) + $tracked_topics = get_tracked_topics(); + +// Load the misc.php language file +require PUN_ROOT.'lang/'.$pun_user['language'].'/misc.php'; + + +// All other topic moderation features require a topic ID in GET +if (isset($_GET['tid'])) +{ + $tid = intval($_GET['tid']); + if ($tid < 1) + message($lang_common['Bad request']); + + // Fetch some info about the topic + $result = $db->query('SELECT t.subject, t.num_replies, t.first_post_id, f.id AS forum_id, forum_name FROM '.$db->prefix.'topics AS t INNER JOIN '.$db->prefix.'forums AS f ON f.id=t.forum_id LEFT JOIN '.$db->prefix.'subscriptions AS s ON (t.id=s.topic_id AND s.user_id='.$pun_user['id'].') LEFT JOIN '.$db->prefix.'forum_perms AS fp ON (fp.forum_id=f.id AND fp.group_id='.$pun_user['g_id'].') WHERE (fp.read_forum IS NULL OR fp.read_forum=1) AND f.id='.$fid.' AND t.id='.$tid.' AND t.moved_to IS NULL') or error('Unable to fetch topic info', __FILE__, __LINE__, $db->error()); + if (!$db->num_rows($result)) + message($lang_common['Bad request']); + + $cur_topic = $db->fetch_assoc($result); + + // Delete one or more posts + if (isset($_POST['delete_posts']) || isset($_POST['delete_posts_comply'])) + { + $posts = isset($_POST['posts']) ? $_POST['posts'] : array(); + if (empty($posts)) + message($lang_misc['No posts selected']); + + if (isset($_POST['delete_posts_comply'])) + { + confirm_referrer('moderate.php'); + + if (@preg_match('/[^0-9,]/', $posts)) + message($lang_common['Bad request']); + + // Verify that the post IDs are valid + $result = $db->query('SELECT 1 FROM '.$db->prefix.'posts WHERE id IN('.$posts.') AND topic_id='.$tid) or error('Unable to check posts', __FILE__, __LINE__, $db->error()); + + if ($db->num_rows($result) != substr_count($posts, ',') + 1) + message($lang_common['Bad request']); + + // Delete the posts + $db->query('DELETE FROM '.$db->prefix.'posts WHERE id IN('.$posts.')') or error('Unable to delete posts', __FILE__, __LINE__, $db->error()); + + require PUN_ROOT.'include/search_idx.php'; + strip_search_index($posts); + + // Get last_post, last_post_id, and last_poster for the topic after deletion + $result = $db->query('SELECT id, poster, posted FROM '.$db->prefix.'posts WHERE topic_id='.$tid.' ORDER BY id DESC LIMIT 1') or error('Unable to fetch post info', __FILE__, __LINE__, $db->error()); + $last_post = $db->fetch_assoc($result); + + // How many posts did we just delete? + $num_posts_deleted = substr_count($posts, ',') + 1; + + // Update the topic + $db->query('UPDATE '.$db->prefix.'topics SET last_post='.$last_post['posted'].', last_post_id='.$last_post['id'].', last_poster=\''.$db->escape($last_post['poster']).'\', num_replies=num_replies-'.$num_posts_deleted.' WHERE id='.$tid) or error('Unable to update topic', __FILE__, __LINE__, $db->error()); + + update_forum($fid); + + redirect('viewtopic.php?id='.$tid, $lang_misc['Delete posts redirect']); + } + + + $page_title = array(pun_htmlspecialchars($pun_config['o_board_title']), $lang_misc['Moderate']); + define('PUN_ACTIVE_PAGE', 'index'); + require PUN_ROOT.'header.php'; + +?> +
    +

    +
    +
    +
    +
    + +
    + +

    +
    +
    +
    +

    +
    +
    +
    +query('SELECT 1 FROM '.$db->prefix.'posts WHERE id IN('.$posts.') AND topic_id='.$tid) or error('Unable to check posts', __FILE__, __LINE__, $db->error()); + + if ($db->num_rows($result) != $num_posts_splitted) + message($lang_common['Bad request']); + + // Load the post.php language file + require PUN_ROOT.'lang/'.$pun_user['language'].'/post.php'; + + // Check subject + $new_subject = isset($_POST['new_subject']) ? pun_trim($_POST['new_subject']) : ''; + + if ($new_subject == '') + message($lang_post['No subject']); + else if (pun_strlen($new_subject) > 70) + message($lang_post['Too long subject']); + + // Get data from the new first post + $result = $db->query('SELECT p.id, p.poster, p.posted FROM '.$db->prefix.'posts AS p WHERE id IN('.$posts.') ORDER BY p.id ASC LIMIT 1') or error('Unable to get first post', __FILE__, __LINE__, $db->error()); + $first_post_data = $db->fetch_assoc($result); + + // Create the new topic + $db->query('INSERT INTO '.$db->prefix.'topics (poster, subject, posted, first_post_id, forum_id) VALUES (\''.$db->escape($first_post_data['poster']).'\', \''.$db->escape($new_subject).'\', '.$first_post_data['posted'].', '.$first_post_data['id'].', '.$fid.')') or error('Unable to create new topic', __FILE__, __LINE__, $db->error()); + $new_tid = $db->insert_id(); + + // Move the posts to the new topic + $db->query('UPDATE '.$db->prefix.'posts SET topic_id='.$new_tid.' WHERE id IN('.$posts.')') or error('Unable to move posts into new topic', __FILE__, __LINE__, $db->error()); + + // Get last_post, last_post_id, and last_poster from the topic and update it + $result = $db->query('SELECT id, poster, posted FROM '.$db->prefix.'posts WHERE topic_id='.$tid.' ORDER BY id DESC LIMIT 1') or error('Unable to fetch post info', __FILE__, __LINE__, $db->error()); + $last_post_data = $db->fetch_assoc($result); + $db->query('UPDATE '.$db->prefix.'topics SET last_post='.$last_post_data['posted'].', last_post_id='.$last_post_data['id'].', last_poster=\''.$db->escape($last_post_data['poster']).'\', num_replies=num_replies-'.$num_posts_splitted.' WHERE id='.$tid) or error('Unable to update topic', __FILE__, __LINE__, $db->error()); + + // Get last_post, last_post_id, and last_poster from the new topic and update it + $result = $db->query('SELECT id, poster, posted FROM '.$db->prefix.'posts WHERE topic_id='.$new_tid.' ORDER BY id DESC LIMIT 1') or error('Unable to fetch post info', __FILE__, __LINE__, $db->error()); + $last_post_data = $db->fetch_assoc($result); + $db->query('UPDATE '.$db->prefix.'topics SET last_post='.$last_post_data['posted'].', last_post_id='.$last_post_data['id'].', last_poster=\''.$db->escape($last_post_data['poster']).'\', num_replies='.($num_posts_splitted-1).' WHERE id='.$new_tid) or error('Unable to update topic', __FILE__, __LINE__, $db->error()); + + update_forum($fid); + + redirect('viewtopic.php?id='.$new_tid, $lang_misc['Split posts redirect']); + } + + $page_title = array(pun_htmlspecialchars($pun_config['o_board_title']), $lang_misc['Moderate']); + $focus_element = array('subject','new_subject'); + define('PUN_ACTIVE_PAGE', 'index'); + require PUN_ROOT.'header.php'; + +?> +
    +

    +
    +
    +
    +
    + +
    + + +

    +
    +
    +
    +

    +
    +
    +
    + $num_pages) ? 1 : intval($_GET['p']); + $start_from = $pun_user['disp_posts'] * ($p - 1); + + // Generate paging links + $paging_links = ''.$lang_common['Pages'].' '.paginate($num_pages, $p, 'moderate.php?fid='.$fid.'&tid='.$tid); + + + if ($pun_config['o_censoring'] == '1') + $cur_topic['subject'] = censor_words($cur_topic['subject']); + + + $page_title = array(pun_htmlspecialchars($pun_config['o_board_title']), pun_htmlspecialchars($cur_topic['forum_name']), pun_htmlspecialchars($cur_topic['subject'])); + define('PUN_ACTIVE_PAGE', 'index'); + require PUN_ROOT.'header.php'; + +?> +
    +
    +
      +
    • +
    • » 
    • +
    • » 
    • +
    • » 
    • +
    +
    + +
    +
    +
    +
    + +
    +query('SELECT id FROM '.$db->prefix.'posts WHERE topic_id='.$tid.' ORDER BY id LIMIT '.$start_from.','.$pun_user['disp_posts']) or error('Unable to fetch post IDs', __FILE__, __LINE__, $db->error()); + + $post_ids = array(); + for ($i = 0;$cur_post_id = $db->result($result, $i);$i++) + $post_ids[] = $cur_post_id; + + // Retrieve the posts (and their respective poster) + $result = $db->query('SELECT u.title, u.num_posts, g.g_id, g.g_user_title, p.id, p.poster, p.poster_id, p.message, p.hide_smilies, p.posted, p.edited, p.edited_by FROM '.$db->prefix.'posts AS p INNER JOIN '.$db->prefix.'users AS u ON u.id=p.poster_id INNER JOIN '.$db->prefix.'groups AS g ON g.g_id=u.group_id WHERE p.id IN ('.implode(',', $post_ids).') ORDER BY p.id', true) or error('Unable to fetch post info', __FILE__, __LINE__, $db->error()); + + while ($cur_post = $db->fetch_assoc($result)) + { + $post_count++; + + // If the poster is a registered user + if ($cur_post['poster_id'] > 1) + { + if ($pun_user['g_view_users'] == '1') + $poster = ''.pun_htmlspecialchars($cur_post['poster']).''; + else + $poster = pun_htmlspecialchars($cur_post['poster']); + + // get_title() requires that an element 'username' be present in the array + $cur_post['username'] = $cur_post['poster']; + $user_title = get_title($cur_post); + + if ($pun_config['o_censoring'] == '1') + $user_title = censor_words($user_title); + } + // If the poster is a guest (or a user that has been deleted) + else + { + $poster = pun_htmlspecialchars($cur_post['poster']); + $user_title = $lang_topic['Guest']; + } + + // Perform the main parsing of the message (BBCode, smilies, censor words etc) + $cur_post['message'] = parse_message($cur_post['message'], $cur_post['hide_smilies']); + +?> + +
    +

    #

    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +

    +
    + +'.$lang_topic['Last edit'].' '.pun_htmlspecialchars($cur_post['edited_by']).' ('.format_time($cur_post['edited']).')

    '."\n"; ?> +
    +
    +
    +
    +
    +
    +

    ' : '

    '.$lang_misc['Cannot select first'].'

    ' ?>
    +
    +
    +
    +
    + + +
    +
    +
    + +

    /> />

    +
    +
    +
    +
    +query('SELECT 1 FROM '.$db->prefix.'topics WHERE id IN('.implode(',',$topics).') AND forum_id='.$fid) or error('Unable to check topics', __FILE__, __LINE__, $db->error()); + + if ($db->num_rows($result) != count($topics)) + message($lang_common['Bad request']); + + // Delete any redirect topics if there are any (only if we moved/copied the topic back to where it was once moved from) + $db->query('DELETE FROM '.$db->prefix.'topics WHERE forum_id='.$move_to_forum.' AND moved_to IN('.implode(',',$topics).')') or error('Unable to delete redirect topics', __FILE__, __LINE__, $db->error()); + + // Move the topic(s) + $db->query('UPDATE '.$db->prefix.'topics SET forum_id='.$move_to_forum.' WHERE id IN('.implode(',',$topics).')') or error('Unable to move topics', __FILE__, __LINE__, $db->error()); + + // Should we create redirect topics? + if (isset($_POST['with_redirect'])) + { + foreach ($topics as $cur_topic) + { + // Fetch info for the redirect topic + $result = $db->query('SELECT poster, subject, posted, last_post FROM '.$db->prefix.'topics WHERE id='.$cur_topic) or error('Unable to fetch topic info', __FILE__, __LINE__, $db->error()); + $moved_to = $db->fetch_assoc($result); + + // Create the redirect topic + $db->query('INSERT INTO '.$db->prefix.'topics (poster, subject, posted, last_post, moved_to, forum_id) VALUES(\''.$db->escape($moved_to['poster']).'\', \''.$db->escape($moved_to['subject']).'\', '.$moved_to['posted'].', '.$moved_to['last_post'].', '.$cur_topic.', '.$fid.')') or error('Unable to create redirect topic', __FILE__, __LINE__, $db->error()); + } + } + + update_forum($fid); // Update the forum FROM which the topic was moved + update_forum($move_to_forum); // Update the forum TO which the topic was moved + + $redirect_msg = (count($topics) > 1) ? $lang_misc['Move topics redirect'] : $lang_misc['Move topic redirect']; + redirect('viewforum.php?id='.$move_to_forum, $redirect_msg); + } + + if (isset($_POST['move_topics'])) + { + $topics = isset($_POST['topics']) ? $_POST['topics'] : array(); + if (empty($topics)) + message($lang_misc['No topics selected']); + + $topics = implode(',', array_map('intval', array_keys($topics))); + $action = 'multi'; + } + else + { + $topics = intval($_GET['move_topics']); + if ($topics < 1) + message($lang_common['Bad request']); + + $action = 'single'; + } + + $result = $db->query('SELECT c.id AS cid, c.cat_name, f.id AS fid, f.forum_name FROM '.$db->prefix.'categories AS c INNER JOIN '.$db->prefix.'forums AS f ON c.id=f.cat_id LEFT JOIN '.$db->prefix.'forum_perms AS fp ON (fp.forum_id=f.id AND fp.group_id='.$pun_user['g_id'].') WHERE (fp.read_forum IS NULL OR fp.read_forum=1) AND f.redirect_url IS NULL ORDER BY c.disp_position, c.id, f.disp_position') or error('Unable to fetch category/forum list', __FILE__, __LINE__, $db->error()); + if ($db->num_rows($result) < 2) + message($lang_misc['Nowhere to move']); + + $page_title = array(pun_htmlspecialchars($pun_config['o_board_title']), $lang_misc['Moderate']); + define('PUN_ACTIVE_PAGE', 'index'); + require PUN_ROOT.'header.php'; + +?> +
    +

    +
    +
    +
    + +
    + +
    + +
    + +
    +
    +
    +
    +

    +
    +
    +
    +query('SELECT 1 FROM '.$db->prefix.'topics WHERE id IN('.implode(',', $topics).') AND moved_to IS NULL AND forum_id='.$fid) or error('Unable to check topics', __FILE__, __LINE__, $db->error()); + $result = $db->query('SELECT 1 FROM '.$db->prefix.'topics WHERE id IN('.implode(',', $topics).') AND forum_id='.$fid) or error('Unable to check topics', __FILE__, __LINE__, $db->error()); + if ($db->num_rows($result) != count($topics)) + message($lang_common['Bad request']); + + // Fetch the topic that we're merging into + $result = $db->query('SELECT MIN(t.id) FROM '.$db->prefix.'topics AS t WHERE t.id IN('.implode(',', $topics).')') or error('Unable to get topic', __FILE__, __LINE__, $db->error()); + $merge_to_tid = $db->result($result); + + // Make any redirect topics point to our new, merged topic + $query = 'UPDATE '.$db->prefix.'topics SET moved_to='.$merge_to_tid.' WHERE moved_to IN('.implode(',', $topics).')'; + + // Should we create redirect topics? + if (isset($_POST['with_redirect'])) + $query .= ' OR (id IN('.implode(',', $topics).') AND id != '.$merge_to_tid.')'; + + $db->query($query) or error('Unable to make redirection topics', __FILE__, __LINE__, $db->error()); + + // Merge the posts into the topic + $db->query('UPDATE '.$db->prefix.'posts SET topic_id='.$merge_to_tid.' WHERE topic_id IN('.implode(',', $topics).')') or error('Unable to merge the posts into the topic', __FILE__, __LINE__, $db->error()); + + // Delete any subscriptions + $db->query('DELETE FROM '.$db->prefix.'subscriptions WHERE topic_id IN('.implode(',', $topics).') AND topic_id != '.$merge_to_tid) or error('Unable to delete subscriptions', __FILE__, __LINE__, $db->error()); + + // Without redirection the old topics are removed + if (!isset($_POST['with_redirect'])) + $db->query('DELETE FROM '.$db->prefix.'topics WHERE id IN('.implode(',', $topics).') AND id != '.$merge_to_tid) or error('Unable to delete old topics', __FILE__, __LINE__, $db->error()); + + // Count number of replies in the topic + $result = $db->query('SELECT COUNT(id) FROM '.$db->prefix.'posts WHERE topic_id='.$merge_to_tid) or error('Unable to fetch post count for topic', __FILE__, __LINE__, $db->error()); + $num_replies = $db->result($result, 0) - 1; + + // Get last_post, last_post_id and last_poster + $result = $db->query('SELECT posted, id, poster FROM '.$db->prefix.'posts WHERE topic_id='.$merge_to_tid.' ORDER BY id DESC LIMIT 1') or error('Unable to get last post info', __FILE__, __LINE__, $db->error()); + list($last_post, $last_post_id, $last_poster) = $db->fetch_row($result); + + // Update topic + $db->query('UPDATE '.$db->prefix.'topics SET num_replies='.$num_replies.', last_post='.$last_post.', last_post_id='.$last_post_id.', last_poster=\''.$db->escape($last_poster).'\' WHERE id='.$merge_to_tid) or error('Unable to update topic', __FILE__, __LINE__, $db->error()); + + // Update the forum FROM which the topic was moved and redirect + update_forum($fid); + redirect('viewforum.php?id='.$fid, $lang_misc['Merge topics redirect']); + } + + $topics = isset($_POST['topics']) ? $_POST['topics'] : array(); + if (count($topics) < 2) + message($lang_misc['Not enough topics selected']); + + $page_title = array(pun_htmlspecialchars($pun_config['o_board_title']), $lang_misc['Moderate']); + define('PUN_ACTIVE_PAGE', 'index'); + require PUN_ROOT.'header.php'; + +?> +
    +

    +
    +
    + +
    +
    + +
    +
    + +
    +
    +
    +
    +

    +
    +
    +
    +query('SELECT 1 FROM '.$db->prefix.'topics WHERE id IN('.$topics.') AND forum_id='.$fid) or error('Unable to check topics', __FILE__, __LINE__, $db->error()); + + if ($db->num_rows($result) != substr_count($topics, ',') + 1) + message($lang_common['Bad request']); + + // Delete the topics and any redirect topics + $db->query('DELETE FROM '.$db->prefix.'topics WHERE id IN('.$topics.') OR moved_to IN('.$topics.')') or error('Unable to delete topic', __FILE__, __LINE__, $db->error()); + + // Delete any subscriptions + $db->query('DELETE FROM '.$db->prefix.'subscriptions WHERE topic_id IN('.$topics.')') or error('Unable to delete subscriptions', __FILE__, __LINE__, $db->error()); + + // Create a list of the post IDs in this topic and then strip the search index + $result = $db->query('SELECT id FROM '.$db->prefix.'posts WHERE topic_id IN('.$topics.')') or error('Unable to fetch posts', __FILE__, __LINE__, $db->error()); + + $post_ids = ''; + while ($row = $db->fetch_row($result)) + $post_ids .= ($post_ids != '') ? ','.$row[0] : $row[0]; + + // We have to check that we actually have a list of post IDs since we could be deleting just a redirect topic + if ($post_ids != '') + strip_search_index($post_ids); + + // Delete posts + $db->query('DELETE FROM '.$db->prefix.'posts WHERE topic_id IN('.$topics.')') or error('Unable to delete posts', __FILE__, __LINE__, $db->error()); + + update_forum($fid); + + redirect('viewforum.php?id='.$fid, $lang_misc['Delete topics redirect']); + } + + + $page_title = array(pun_htmlspecialchars($pun_config['o_board_title']), $lang_misc['Moderate']); + define('PUN_ACTIVE_PAGE', 'index'); + require PUN_ROOT.'header.php'; + +?> +
    +

    +
    +
    + +
    +
    + +
    +

    +
    +
    +
    +

    +
    +
    +
    +query('UPDATE '.$db->prefix.'topics SET closed='.$action.' WHERE id IN('.implode(',', $topics).') AND forum_id='.$fid) or error('Unable to close topics', __FILE__, __LINE__, $db->error()); + + $redirect_msg = ($action) ? $lang_misc['Close topics redirect'] : $lang_misc['Open topics redirect']; + redirect('moderate.php?fid='.$fid, $redirect_msg); + } + // Or just one in $_GET + else + { + confirm_referrer('viewtopic.php'); + + $topic_id = ($action) ? intval($_GET['close']) : intval($_GET['open']); + if ($topic_id < 1) + message($lang_common['Bad request']); + + $db->query('UPDATE '.$db->prefix.'topics SET closed='.$action.' WHERE id='.$topic_id.' AND forum_id='.$fid) or error('Unable to close topic', __FILE__, __LINE__, $db->error()); + + $redirect_msg = ($action) ? $lang_misc['Close topic redirect'] : $lang_misc['Open topic redirect']; + redirect('viewtopic.php?id='.$topic_id, $redirect_msg); + } +} + + +// Stick a topic +else if (isset($_GET['stick'])) +{ + confirm_referrer('viewtopic.php'); + + $stick = intval($_GET['stick']); + if ($stick < 1) + message($lang_common['Bad request']); + + $db->query('UPDATE '.$db->prefix.'topics SET sticky=\'1\' WHERE id='.$stick.' AND forum_id='.$fid) or error('Unable to stick topic', __FILE__, __LINE__, $db->error()); + + redirect('viewtopic.php?id='.$stick, $lang_misc['Stick topic redirect']); +} + + +// Unstick a topic +else if (isset($_GET['unstick'])) +{ + confirm_referrer('viewtopic.php'); + + $unstick = intval($_GET['unstick']); + if ($unstick < 1) + message($lang_common['Bad request']); + + $db->query('UPDATE '.$db->prefix.'topics SET sticky=\'0\' WHERE id='.$unstick.' AND forum_id='.$fid) or error('Unable to unstick topic', __FILE__, __LINE__, $db->error()); + + redirect('viewtopic.php?id='.$unstick, $lang_misc['Unstick topic redirect']); +} + + +// No specific forum moderation action was specified in the query string, so we'll display the moderator forum + +// Load the viewforum.php language file +require PUN_ROOT.'lang/'.$pun_user['language'].'/forum.php'; + +// Fetch some info about the forum +$result = $db->query('SELECT f.forum_name, f.redirect_url, f.num_topics, f.sort_by FROM '.$db->prefix.'forums AS f LEFT JOIN '.$db->prefix.'forum_perms AS fp ON (fp.forum_id=f.id AND fp.group_id='.$pun_user['g_id'].') WHERE (fp.read_forum IS NULL OR fp.read_forum=1) AND f.id='.$fid) or error('Unable to fetch forum info', __FILE__, __LINE__, $db->error()); +if (!$db->num_rows($result)) + message($lang_common['Bad request']); + +$cur_forum = $db->fetch_assoc($result); + +// Is this a redirect forum? In that case, abort! +if ($cur_forum['redirect_url'] != '') + message($lang_common['Bad request']); + +// Determine the topic offset (based on $_GET['p']) +$num_pages = ceil($cur_forum['num_topics'] / $pun_user['disp_topics']); + +$p = (!isset($_GET['p']) || $_GET['p'] <= 1 || $_GET['p'] > $num_pages) ? 1 : intval($_GET['p']); +$start_from = $pun_user['disp_topics'] * ($p - 1); + +// Generate paging links +$paging_links = ''.$lang_common['Pages'].' '.paginate($num_pages, $p, 'moderate.php?fid='.$fid); + +$page_title = array(pun_htmlspecialchars($pun_config['o_board_title']), pun_htmlspecialchars($cur_forum['forum_name'])); +define('PUN_ACTIVE_PAGE', 'index'); +require PUN_ROOT.'header.php'; + +?> +
    +
    +
      +
    • +
    • » 
    • +
    • » 
    • +
    +
    + +
    +
    +
    +
    + +
    +
    +

    +
    +
    + + + + + + + + + + + +query('SELECT id, poster, subject, posted, last_post, last_post_id, last_poster, num_views, num_replies, closed, sticky, moved_to FROM '.$db->prefix.'topics WHERE forum_id='.$fid.' ORDER BY sticky DESC, '.(($cur_forum['sort_by'] == '1') ? 'posted' : 'last_post').' DESC LIMIT '.$start_from.', '.$pun_user['disp_topics']) or error('Unable to fetch topic list for forum', __FILE__, __LINE__, $db->error()); + +// If there are topics in this forum +if ($db->num_rows($result)) +{ + $button_status = ''; + $topic_count = 0; + while ($cur_topic = $db->fetch_assoc($result)) + { + + ++$topic_count; + $status_text = array(); + $item_status = ($topic_count % 2 == 0) ? 'roweven' : 'rowodd'; + $icon_type = 'icon'; + + if ($cur_topic['moved_to'] == null) + { + $last_post = ''.format_time($cur_topic['last_post']).''.$lang_common['by'].' '.pun_htmlspecialchars($cur_topic['last_poster']).''; + $ghost_topic = false; + } + else + { + $last_post = '- - -'; + $ghost_topic = true; + } + + if ($pun_config['o_censoring'] == '1') + $cur_topic['subject'] = censor_words($cur_topic['subject']); + + if ($cur_topic['sticky'] == '1') + { + $item_status .= ' isticky'; + $status_text[] = ''.$lang_forum['Sticky'].''; + } + + if ($cur_topic['moved_to'] != 0) + { + $subject = ''.pun_htmlspecialchars($cur_topic['subject']).''.$lang_common['by'].' '.pun_htmlspecialchars($cur_topic['poster']).''; + $status_text[] = ''.$lang_forum['Moved'].''; + $item_status .= ' imoved'; + } + else if ($cur_topic['closed'] == '0') + $subject = ''.pun_htmlspecialchars($cur_topic['subject']).''.$lang_common['by'].' '.pun_htmlspecialchars($cur_topic['poster']).''; + else + { + $subject = ''.pun_htmlspecialchars($cur_topic['subject']).''.$lang_common['by'].' '.pun_htmlspecialchars($cur_topic['poster']).''; + $status_text[] = ''.$lang_forum['Closed'].''; + $item_status .= ' iclosed'; + } + + if (!$ghost_topic && $cur_topic['last_post'] > $pun_user['last_visit'] && (!isset($tracked_topics['topics'][$cur_topic['id']]) || $tracked_topics['topics'][$cur_topic['id']] < $cur_topic['last_post']) && (!isset($tracked_topics['forums'][$fid]) || $tracked_topics['forums'][$fid] < $cur_topic['last_post'])) + { + $item_status .= ' inew'; + $icon_type = 'icon icon-new'; + $subject = ''.$subject.''; + $subject_new_posts = '[ '.$lang_common['New posts'].' ]'; + } + else + $subject_new_posts = null; + + // Insert the status text before the subject + $subject = implode(' ', $status_text).' '.$subject; + + $num_pages_topic = ceil(($cur_topic['num_replies'] + 1) / $pun_user['disp_posts']); + + if ($num_pages_topic > 1) + $subject_multipage = '[ '.paginate($num_pages_topic, -1, 'viewtopic.php?id='.$cur_topic['id']).' ]'; + else + $subject_multipage = null; + + // Should we show the "New posts" and/or the multipage links? + if (!empty($subject_new_posts) || !empty($subject_multipage)) + { + $subject .= !empty($subject_new_posts) ? ' '.$subject_new_posts : ''; + $subject .= !empty($subject_multipage) ? ' '.$subject_multipage : ''; + } + +?> + + + + + + + +'."\n"; +} + +?> + +
    +
    +
    +
    + +
    +
    +
    '.$lang_forum['Empty forum'].'
    +
    +
    +
    + +
    +
    +
    + +

    /> /> /> /> />

    +
    +
    +
    +
    + tags and the target +## URL for the redirect() function must be set to the value of +## $_SERVER['REQUEST_URI']. This URL can however be extended to +## include extra variables (like the addition of &foo=bar in +## the form of this example plugin). +## +## 4. If your plugin is for administrators only, the filename must +## have the prefix "AP_". If it is for both administrators and +## moderators, use the prefix "AMP_". This example plugin has the +## prefix "AMP_" and is therefore available for both admins and +## moderators in the navigation menu. +## +## 5. Use _ instead of spaces in the file name. +## +## 6. Since plugin scripts are included from the FluxBB script +## admin_loader.php, you have access to all FluxBB functions and +## global variables (e.g. $db, $pun_config, $pun_user etc). +## +## 7. Do your best to keep the look and feel of your plugins' user +## interface similar to the rest of the admin scripts. Feel free to +## borrow markup and code from the admin scripts to use in your +## plugins. If you create your own styles they need to be added to +## the "base_admin" style sheet. +## +## 8. Plugins must be released under the GNU General Public License or +## a GPL compatible license. Copy the GPL preamble at the top of +## this file into your plugin script and alter the copyright notice +## to refrect the author of the plugin (i.e. you). +## +## + + +// Make sure no one attempts to run this script "directly" +if (!defined('PUN')) + exit; + +// Load the admin_bans.php language file +require PUN_ROOT.'lang/'.$admin_language.'/admin_plugin_example.php'; + +// Tell admin_loader.php that this is indeed a plugin and that it is loaded +define('PUN_PLUGIN_LOADED', 1); + +// +// The rest is up to you! +// + +// If the "Show text" button was clicked +if (isset($_POST['show_text'])) +{ + // Make sure something was entered + if (trim($_POST['text_to_show']) == '') + message($lang_admin_plugin_example['No text']); + + // Display the admin navigation menu + generate_admin_menu($plugin); + +?> +
    +

    +
    +
    +

    +

    +
    +
    +
    + +
    +

    +
    +
    +

    +

    +
    +
    + +

    +
    +
    +
    +
    + +
    + + + + + +
    + + +
    +
    +
    +
    +
    +
    +
    +.. diff --git a/post.php b/post.php new file mode 100644 index 0000000..b255172 --- /dev/null +++ b/post.php @@ -0,0 +1,616 @@ + 0 && $fid > 0) + message($lang_common['Bad request']); + +// Fetch some info about the topic and/or the forum +if ($tid) + $result = $db->query('SELECT f.id, f.forum_name, f.moderators, f.redirect_url, fp.post_replies, fp.post_topics, t.subject, t.closed, s.user_id AS is_subscribed FROM '.$db->prefix.'topics AS t INNER JOIN '.$db->prefix.'forums AS f ON f.id=t.forum_id LEFT JOIN '.$db->prefix.'forum_perms AS fp ON (fp.forum_id=f.id AND fp.group_id='.$pun_user['g_id'].') LEFT JOIN '.$db->prefix.'subscriptions AS s ON (t.id=s.topic_id AND s.user_id='.$pun_user['id'].') WHERE (fp.read_forum IS NULL OR fp.read_forum=1) AND t.id='.$tid) or error('Unable to fetch forum info', __FILE__, __LINE__, $db->error()); +else + $result = $db->query('SELECT f.id, f.forum_name, f.moderators, f.redirect_url, fp.post_replies, fp.post_topics FROM '.$db->prefix.'forums AS f LEFT JOIN '.$db->prefix.'forum_perms AS fp ON (fp.forum_id=f.id AND fp.group_id='.$pun_user['g_id'].') WHERE (fp.read_forum IS NULL OR fp.read_forum=1) AND f.id='.$fid) or error('Unable to fetch forum info', __FILE__, __LINE__, $db->error()); + +if (!$db->num_rows($result)) + message($lang_common['Bad request']); + +$cur_posting = $db->fetch_assoc($result); +$is_subscribed = $tid && $cur_posting['is_subscribed']; + +// Is someone trying to post into a redirect forum? +if ($cur_posting['redirect_url'] != '') + message($lang_common['Bad request']); + +// Sort out who the moderators are and if we are currently a moderator (or an admin) +$mods_array = ($cur_posting['moderators'] != '') ? unserialize($cur_posting['moderators']) : array(); +$is_admmod = ($pun_user['g_id'] == PUN_ADMIN || ($pun_user['g_moderator'] == '1' && array_key_exists($pun_user['username'], $mods_array))) ? true : false; + +if ($pun_config['o_censoring'] == '1') + $cur_posting['subject'] = censor_words($cur_posting['subject']); + +// Do we have permission to post? +if ((($tid && (($cur_posting['post_replies'] == '' && $pun_user['g_post_replies'] == '0') || $cur_posting['post_replies'] == '0')) || + ($fid && (($cur_posting['post_topics'] == '' && $pun_user['g_post_topics'] == '0') || $cur_posting['post_topics'] == '0')) || + (isset($cur_posting['closed']) && $cur_posting['closed'] == '1')) && + !$is_admmod) + message($lang_common['No permission']); + +// Load the post.php language file +require PUN_ROOT.'lang/'.$pun_user['language'].'/post.php'; + +// Start with a clean slate +$errors = array(); + + +// Did someone just hit "Submit" or "Preview"? +if (isset($_POST['form_sent'])) +{ + // Make sure form_user is correct + if (($pun_user['is_guest'] && $_POST['form_user'] != 'Guest') || (!$pun_user['is_guest'] && $_POST['form_user'] != $pun_user['username'])) + message($lang_common['Bad request']); + + // Flood protection + if (!isset($_POST['preview']) && $pun_user['last_post'] != '' && (time() - $pun_user['last_post']) < $pun_user['g_post_flood']) + $errors[] = $lang_post['Flood start'].' '.$pun_user['g_post_flood'].' '.$lang_post['flood end']; + + // If it's a new topic + if ($fid) + { + $subject = pun_trim($_POST['req_subject']); + + if ($subject == '') + $errors[] = $lang_post['No subject']; + else if (pun_strlen($subject) > 70) + $errors[] = $lang_post['Too long subject']; + else if ($pun_config['p_subject_all_caps'] == '0' && is_all_uppercase($subject) && !$pun_user['is_admmod']) + $errors[] = $lang_post['All caps subject']; + } + + // If the user is logged in we get the username and email from $pun_user + if (!$pun_user['is_guest']) + { + $username = $pun_user['username']; + $email = $pun_user['email']; + } + // Otherwise it should be in $_POST + else + { + $username = pun_trim($_POST['req_username']); + $email = strtolower(trim(($pun_config['p_force_guest_email'] == '1') ? $_POST['req_email'] : $_POST['email'])); + + // Load the register.php/profile.php language files + require PUN_ROOT.'lang/'.$pun_user['language'].'/prof_reg.php'; + require PUN_ROOT.'lang/'.$pun_user['language'].'/register.php'; + + // It's a guest, so we have to validate the username + check_username($username); + + if ($pun_config['p_force_guest_email'] == '1' || $email != '') + { + require PUN_ROOT.'include/email.php'; + if (!is_valid_email($email)) + $errors[] = $lang_common['Invalid email']; + + // Check if it's a banned email address + // we should only check guests because members addresses are already verified + if ($pun_user['is_guest'] && is_banned_email($email)) + { + if ($pun_config['p_allow_banned_email'] == '0') + $errors[] = $lang_prof_reg['Banned email']; + + $banned_email = true; // Used later when we send an alert email + } + else + $banned_email = false; + } + } + + // Clean up message from POST + $message = pun_linebreaks(pun_trim($_POST['req_message'])); + + if (pun_strlen($message) > PUN_MAX_POSTSIZE) + $errors[] = $lang_post['Too long message']; + else if ($pun_config['p_message_all_caps'] == '0' && is_all_uppercase($message) && !$pun_user['is_admmod']) + $errors[] = $lang_post['All caps message']; + + // Validate BBCode syntax + if ($pun_config['p_message_bbcode'] == '1') + { + require PUN_ROOT.'include/parser.php'; + $message = preparse_bbcode($message, $errors); + } + + if ($message == '') + $errors[] = $lang_post['No message']; + + $hide_smilies = isset($_POST['hide_smilies']) ? '1' : '0'; + $subscribe = isset($_POST['subscribe']) ? '1' : '0'; + + $now = time(); + + // Did everything go according to plan? + if (empty($errors) && !isset($_POST['preview'])) + { + require PUN_ROOT.'include/search_idx.php'; + + // If it's a reply + if ($tid) + { + if (!$pun_user['is_guest']) + { + $new_tid = $tid; + + // Insert the new post + $db->query('INSERT INTO '.$db->prefix.'posts (poster, poster_id, poster_ip, message, hide_smilies, posted, topic_id) VALUES(\''.$db->escape($username).'\', '.$pun_user['id'].', \''.get_remote_address().'\', \''.$db->escape($message).'\', '.$hide_smilies.', '.$now.', '.$tid.')') or error('Unable to create post', __FILE__, __LINE__, $db->error()); + $new_pid = $db->insert_id(); + + // To subscribe or not to subscribe, that ... + if ($pun_config['o_subscriptions'] == '1') + { + if ($subscribe && !$is_subscribed) + $db->query('INSERT INTO '.$db->prefix.'subscriptions (user_id, topic_id) VALUES('.$pun_user['id'].' ,'.$tid.')') or error('Unable to add subscription', __FILE__, __LINE__, $db->error()); + else if (!$subscribe && $is_subscribed) + $db->query('DELETE FROM '.$db->prefix.'subscriptions WHERE user_id='.$pun_user['id'].' AND topic_id='.$tid) or error('Unable to remove subscription', __FILE__, __LINE__, $db->error()); + } + } + else + { + // It's a guest. Insert the new post + $email_sql = ($pun_config['p_force_guest_email'] == '1' || $email != '') ? '\''.$email.'\'' : 'NULL'; + $db->query('INSERT INTO '.$db->prefix.'posts (poster, poster_ip, poster_email, message, hide_smilies, posted, topic_id) VALUES(\''.$db->escape($username).'\', \''.get_remote_address().'\', '.$email_sql.', \''.$db->escape($message).'\', '.$hide_smilies.', '.$now.', '.$tid.')') or error('Unable to create post', __FILE__, __LINE__, $db->error()); + $new_pid = $db->insert_id(); + } + + // Count number of replies in the topic + $result = $db->query('SELECT COUNT(id) FROM '.$db->prefix.'posts WHERE topic_id='.$tid) or error('Unable to fetch post count for topic', __FILE__, __LINE__, $db->error()); + $num_replies = $db->result($result, 0) - 1; + + // Update topic + $db->query('UPDATE '.$db->prefix.'topics SET num_replies='.$num_replies.', last_post='.$now.', last_post_id='.$new_pid.', last_poster=\''.$db->escape($username).'\' WHERE id='.$tid) or error('Unable to update topic', __FILE__, __LINE__, $db->error()); + + update_search_index('post', $new_pid, $message); + + update_forum($cur_posting['id']); + + // Should we send out notifications? + if ($pun_config['o_subscriptions'] == '1') + { + // Get the post time for the previous post in this topic + $result = $db->query('SELECT posted FROM '.$db->prefix.'posts WHERE topic_id='.$tid.' ORDER BY id DESC LIMIT 1, 1') or error('Unable to fetch post info', __FILE__, __LINE__, $db->error()); + $previous_post_time = $db->result($result); + + // Get any subscribed users that should be notified (banned users are excluded) + $result = $db->query('SELECT u.id, u.email, u.notify_with_post, u.language FROM '.$db->prefix.'users AS u INNER JOIN '.$db->prefix.'subscriptions AS s ON u.id=s.user_id LEFT JOIN '.$db->prefix.'forum_perms AS fp ON (fp.forum_id='.$cur_posting['id'].' AND fp.group_id=u.group_id) LEFT JOIN '.$db->prefix.'online AS o ON u.id=o.user_id LEFT JOIN '.$db->prefix.'bans AS b ON u.username=b.username WHERE b.username IS NULL AND COALESCE(o.logged, u.last_visit)>'.$previous_post_time.' AND (fp.read_forum IS NULL OR fp.read_forum=1) AND s.topic_id='.$tid.' AND u.id!='.$pun_user['id']) or error('Unable to fetch subscription info', __FILE__, __LINE__, $db->error()); + if ($db->num_rows($result)) + { + require_once PUN_ROOT.'include/email.php'; + + $notification_emails = array(); + + // Loop through subscribed users and send emails + while ($cur_subscriber = $db->fetch_assoc($result)) + { + // Is the subscription email for $cur_subscriber['language'] cached or not? + if (!isset($notification_emails[$cur_subscriber['language']])) + { + if (file_exists(PUN_ROOT.'lang/'.$cur_subscriber['language'].'/mail_templates/new_reply.tpl')) + { + // Load the "new reply" template + $mail_tpl = trim(file_get_contents(PUN_ROOT.'lang/'.$cur_subscriber['language'].'/mail_templates/new_reply.tpl')); + + // Load the "new reply full" template (with post included) + $mail_tpl_full = trim(file_get_contents(PUN_ROOT.'lang/'.$cur_subscriber['language'].'/mail_templates/new_reply_full.tpl')); + + // The first row contains the subject (it also starts with "Subject:") + $first_crlf = strpos($mail_tpl, "\n"); + $mail_subject = trim(substr($mail_tpl, 8, $first_crlf-8)); + $mail_message = trim(substr($mail_tpl, $first_crlf)); + + $first_crlf = strpos($mail_tpl_full, "\n"); + $mail_subject_full = trim(substr($mail_tpl_full, 8, $first_crlf-8)); + $mail_message_full = trim(substr($mail_tpl_full, $first_crlf)); + + $mail_subject = str_replace('', '\''.$cur_posting['subject'].'\'', $mail_subject); + $mail_message = str_replace('', '\''.$cur_posting['subject'].'\'', $mail_message); + $mail_message = str_replace('', $username, $mail_message); + $mail_message = str_replace('', $pun_config['o_base_url'].'/viewtopic.php?pid='.$new_pid.'#p'.$new_pid, $mail_message); + $mail_message = str_replace('', $pun_config['o_base_url'].'/misc.php?unsubscribe='.$tid, $mail_message); + $mail_message = str_replace('', $pun_config['o_board_title'].' '.$lang_common['Mailer'], $mail_message); + + $mail_subject_full = str_replace('', '\''.$cur_posting['subject'].'\'', $mail_subject_full); + $mail_message_full = str_replace('', '\''.$cur_posting['subject'].'\'', $mail_message_full); + $mail_message_full = str_replace('', $username, $mail_message_full); + $mail_message_full = str_replace('', $message, $mail_message_full); + $mail_message_full = str_replace('', $pun_config['o_base_url'].'/viewtopic.php?pid='.$new_pid.'#p'.$new_pid, $mail_message_full); + $mail_message_full = str_replace('', $pun_config['o_base_url'].'/misc.php?unsubscribe='.$tid, $mail_message_full); + $mail_message_full = str_replace('', $pun_config['o_board_title'].' '.$lang_common['Mailer'], $mail_message_full); + + $notification_emails[$cur_subscriber['language']][0] = $mail_subject; + $notification_emails[$cur_subscriber['language']][1] = $mail_message; + $notification_emails[$cur_subscriber['language']][2] = $mail_subject_full; + $notification_emails[$cur_subscriber['language']][3] = $mail_message_full; + + $mail_subject = $mail_message = $mail_subject_full = $mail_message_full = null; + } + } + + // We have to double check here because the templates could be missing + if (isset($notification_emails[$cur_subscriber['language']])) + { + if ($cur_subscriber['notify_with_post'] == '0') + pun_mail($cur_subscriber['email'], $notification_emails[$cur_subscriber['language']][0], $notification_emails[$cur_subscriber['language']][1]); + else + pun_mail($cur_subscriber['email'], $notification_emails[$cur_subscriber['language']][2], $notification_emails[$cur_subscriber['language']][3]); + } + } + } + } + } + // If it's a new topic + else if ($fid) + { + // Create the topic + $db->query('INSERT INTO '.$db->prefix.'topics (poster, subject, posted, last_post, last_poster, forum_id) VALUES(\''.$db->escape($username).'\', \''.$db->escape($subject).'\', '.$now.', '.$now.', \''.$db->escape($username).'\', '.$fid.')') or error('Unable to create topic', __FILE__, __LINE__, $db->error()); + $new_tid = $db->insert_id(); + + if (!$pun_user['is_guest']) + { + // To subscribe or not to subscribe, that ... + if ($pun_config['o_subscriptions'] == '1' && $subscribe) + $db->query('INSERT INTO '.$db->prefix.'subscriptions (user_id, topic_id) VALUES('.$pun_user['id'].' ,'.$new_tid.')') or error('Unable to add subscription', __FILE__, __LINE__, $db->error()); + + // Create the post ("topic post") + $db->query('INSERT INTO '.$db->prefix.'posts (poster, poster_id, poster_ip, message, hide_smilies, posted, topic_id) VALUES(\''.$db->escape($username).'\', '.$pun_user['id'].', \''.get_remote_address().'\', \''.$db->escape($message).'\', '.$hide_smilies.', '.$now.', '.$new_tid.')') or error('Unable to create post', __FILE__, __LINE__, $db->error()); + } + else + { + // Create the post ("topic post") + $email_sql = ($pun_config['p_force_guest_email'] == '1' || $email != '') ? '\''.$email.'\'' : 'NULL'; + $db->query('INSERT INTO '.$db->prefix.'posts (poster, poster_ip, poster_email, message, hide_smilies, posted, topic_id) VALUES(\''.$db->escape($username).'\', \''.get_remote_address().'\', '.$email_sql.', \''.$db->escape($message).'\', '.$hide_smilies.', '.$now.', '.$new_tid.')') or error('Unable to create post', __FILE__, __LINE__, $db->error()); + } + $new_pid = $db->insert_id(); + + // Update the topic with last_post_id + $db->query('UPDATE '.$db->prefix.'topics SET last_post_id='.$new_pid.', first_post_id='.$new_pid.' WHERE id='.$new_tid) or error('Unable to update topic', __FILE__, __LINE__, $db->error()); + + update_search_index('post', $new_pid, $message, $subject); + + update_forum($fid); + } + + // If we previously found out that the email was banned + if ($pun_user['is_guest'] && $banned_email && $pun_config['o_mailing_list'] != '') + { + $mail_subject = $lang_common['Banned email notification']; + $mail_message = sprintf($lang_common['Banned email post message'], $username, $email)."\n"; + $mail_message .= sprintf($lang_common['Post URL'], $pun_config['o_base_url'].'/viewtopic.php?pid='.$new_pid.'#p'.$new_pid)."\n"; + $mail_message .= "\n".'--'."\n".$lang_common['Email signature']; + + pun_mail($pun_config['o_mailing_list'], $mail_subject, $mail_message); + } + + // If the posting user is logged in, increment his/her post count + if (!$pun_user['is_guest']) + { + $db->query('UPDATE '.$db->prefix.'users SET num_posts=num_posts+1, last_post='.$now.' WHERE id='.$pun_user['id']) or error('Unable to update user', __FILE__, __LINE__, $db->error()); + + $tracked_topics = get_tracked_topics(); + $tracked_topics['topics'][$new_tid] = time(); + set_tracked_topics($tracked_topics); + } + else + { + $db->query('UPDATE '.$db->prefix.'online SET last_post='.$now.' WHERE ident=\''.$db->escape(get_remote_address()).'\'' ) or error('Unable to update user', __FILE__, __LINE__, $db->error()); + } + + redirect('viewtopic.php?pid='.$new_pid.'#p'.$new_pid, $lang_post['Post redirect']); + } +} + + +// If a topic ID was specified in the url (it's a reply) +if ($tid) +{ + $action = $lang_post['Post a reply']; + $form = '
    '; + + // If a quote ID was specified in the url + if (isset($_GET['qid'])) + { + $qid = intval($_GET['qid']); + if ($qid < 1) + message($lang_common['Bad request']); + + $result = $db->query('SELECT poster, message FROM '.$db->prefix.'posts WHERE id='.$qid.' AND topic_id='.$tid) or error('Unable to fetch quote info', __FILE__, __LINE__, $db->error()); + if (!$db->num_rows($result)) + message($lang_common['Bad request']); + + list($q_poster, $q_message) = $db->fetch_row($result); + + $q_message = preg_replace('%\[img(?:=.*?)?\]%', '[url]', $q_message); + $q_message = str_replace('[/img]', '[/url]', $q_message); + + if ($pun_config['o_censoring'] == '1') + $q_message = censor_words($q_message); + + $q_message = pun_htmlspecialchars($q_message); + + if ($pun_config['p_message_bbcode'] == '1') + { + // If username contains a square bracket, we add "" or '' around it (so we know when it starts and ends) + if (strpos($q_poster, '[') !== false || strpos($q_poster, ']') !== false) + { + if (strpos($q_poster, '\'') !== false) + $q_poster = '"'.$q_poster.'"'; + else + $q_poster = '\''.$q_poster.'\''; + } + else + { + // Get the characters at the start and end of $q_poster + $ends = substr($q_poster, 0, 1).substr($q_poster, -1, 1); + + // Deal with quoting "Username" or 'Username' (becomes '"Username"' or "'Username'") + if ($ends == '\'\'') + $q_poster = '"'.$q_poster.'"'; + else if ($ends == '""') + $q_poster = '\''.$q_poster.'\''; + } + + $quote = '[quote='.$q_poster.']'.$q_message.'[/quote]'."\n"; + } + else + $quote = '> '.$q_poster.' '.$lang_common['wrote']."\n\n".'> '.$q_message."\n"; + } +} +// If a forum ID was specified in the url (new topic) +else if ($fid) +{ + $action = $lang_post['Post new topic']; + $form = ''; +} +else + message($lang_common['Bad request']); + + +$page_title = array(pun_htmlspecialchars($pun_config['o_board_title']), $action); +$required_fields = array('req_email' => $lang_common['Email'], 'req_subject' => $lang_common['Subject'], 'req_message' => $lang_common['Message']); +$focus_element = array('post'); + +if (!$pun_user['is_guest']) + $focus_element[] = ($fid) ? 'req_subject' : 'req_message'; +else +{ + $required_fields['req_username'] = $lang_post['Guest name']; + $focus_element[] = 'req_username'; +} + +define('PUN_ACTIVE_PAGE', 'index'); +require PUN_ROOT.'header.php'; + +?> +
    +
    +
      +
    • +
    • » 
    • +
    • » 
    • +
    • » 
    • +
    +
    +
    + + +
    +

    +
    +
    +

    +
      +'.$cur_error.''."\n"; +?> +
    +
    +
    +
    + + +
    +

    +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    + + +
    +

    +
    + +
    +
    + +
    + + +'.$lang_common['Email'].' '.$lang_common['Required'].'' : $lang_common['Email']; + $email_form_name = ($pun_config['p_force_guest_email'] == '1') ? 'req_email' : 'email'; + +?> + + +
    + + + + +
    +
    +'.$lang_post['Hide smilies'].'
    '; + + if ($pun_config['o_subscriptions'] == '1') + { + $subscr_checked = false; + + // If it's a preview + if (isset($_POST['preview'])) + $subscr_checked = isset($_POST['subscribe']) ? true : false; + // If auto subscribed + else if ($pun_user['auto_notify']) + $subscr_checked = true; + // If already subscribed to the topic + else if ($is_subscribed) + $subscr_checked = true; + + $checkboxes[] = ''; + } +} +else if ($pun_config['o_smilies'] == '1') + $checkboxes[] = ''; + +if (!empty($checkboxes)) +{ + +?> +
    +
    +
    + +
    +
    + +
    +
    +
    + +
    +

    + +
    +
    + +query('SELECT poster, message, hide_smilies, posted FROM '.$db->prefix.'posts WHERE topic_id='.$tid.' ORDER BY id DESC LIMIT '.$pun_config['o_topic_review']) or error('Unable to fetch topic review', __FILE__, __LINE__, $db->error()); + +?> + +
    +

    +fetch_assoc($result)) + { + $post_count++; + + $cur_post['message'] = parse_message($cur_post['message'], $cur_post['hide_smilies']); + +?> +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    +
    + +
    +query('SELECT * FROM '.$db->prefix.'users WHERE id='.$id) or error('Unable to fetch new password', __FILE__, __LINE__, $db->error()); + $cur_user = $db->fetch_assoc($result); + + if ($key == '' || $key != $cur_user['activate_key']) + message($lang_profile['Pass key bad'].' '.$pun_config['o_admin_email'].'.'); + else + { + $db->query('UPDATE '.$db->prefix.'users SET password=\''.$cur_user['activate_string'].'\', activate_string=NULL, activate_key=NULL'.(!empty($cur_user['salt']) ? ', salt=NULL' : '').' WHERE id='.$id) or error('Unable to update password', __FILE__, __LINE__, $db->error()); + + message($lang_profile['Pass updated'], true); + } + } + + // Make sure we are allowed to change this users password + if ($pun_user['id'] != $id) + { + if (!$pun_user['is_admmod']) // A regular user trying to change another users password? + message($lang_common['No permission']); + else if ($pun_user['g_moderator'] == '1') // A moderator trying to change a users password? + { + $result = $db->query('SELECT u.group_id, g.g_moderator FROM '.$db->prefix.'users AS u INNER JOIN '.$db->prefix.'groups AS g ON (g.g_id=u.group_id) WHERE u.id='.$id) or error('Unable to fetch user info', __FILE__, __LINE__, $db->error()); + if (!$db->num_rows($result)) + message($lang_common['Bad request']); + + list($group_id, $is_moderator) = $db->fetch_row($result); + + if ($pun_user['g_mod_edit_users'] == '0' || $pun_user['g_mod_change_passwords'] == '0' || $group_id == PUN_ADMIN || $is_moderator == '1') + message($lang_common['No permission']); + } + } + + if (isset($_POST['form_sent'])) + { + if ($pun_user['is_admmod']) + confirm_referrer('profile.php'); + + $old_password = isset($_POST['req_old_password']) ? pun_trim($_POST['req_old_password']) : ''; + $new_password1 = pun_trim($_POST['req_new_password1']); + $new_password2 = pun_trim($_POST['req_new_password2']); + + if ($new_password1 != $new_password2) + message($lang_prof_reg['Pass not match']); + if (pun_strlen($new_password1) < 4) + message($lang_prof_reg['Pass too short']); + + $result = $db->query('SELECT * FROM '.$db->prefix.'users WHERE id='.$id) or error('Unable to fetch password', __FILE__, __LINE__, $db->error()); + $cur_user = $db->fetch_assoc($result); + + $authorized = false; + + if (!empty($cur_user['password'])) + { + $old_password_hash = pun_hash($old_password); + + if ($cur_user['password'] == $old_password_hash || $pun_user['is_admmod']) + $authorized = true; + } + + if (!$authorized) + message($lang_profile['Wrong pass']); + + $new_password_hash = pun_hash($new_password1); + + $db->query('UPDATE '.$db->prefix.'users SET password=\''.$new_password_hash.'\''.(!empty($cur_user['salt']) ? ', salt=NULL' : '').' WHERE id='.$id) or error('Unable to update password', __FILE__, __LINE__, $db->error()); + + if ($pun_user['id'] == $id) + pun_setcookie($pun_user['id'], $new_password_hash, time() + $pun_config['o_timeout_visit']); + + redirect('profile.php?section=essentials&id='.$id, $lang_profile['Pass updated redirect']); + } + + $page_title = array(pun_htmlspecialchars($pun_config['o_board_title']), $lang_common['Profile'], $lang_profile['Change pass']); + $required_fields = array('req_old_password' => $lang_profile['Old pass'], 'req_new_password1' => $lang_profile['New pass'], 'req_new_password2' => $lang_profile['Confirm new pass']); + $focus_element = array('change_pass', ((!$pun_user['is_admmod']) ? 'req_old_password' : 'req_new_password1')); + define('PUN_ACTIVE_PAGE', 'profile'); + require PUN_ROOT.'header.php'; + +?> +
    +

    +
    +
    +
    + +
    + +
    + + + +

    +
    +
    +
    +

    +
    +
    +
    +query('SELECT u.group_id, g.g_moderator FROM '.$db->prefix.'users AS u INNER JOIN '.$db->prefix.'groups AS g ON (g.g_id=u.group_id) WHERE u.id='.$id) or error('Unable to fetch user info', __FILE__, __LINE__, $db->error()); + if (!$db->num_rows($result)) + message($lang_common['Bad request']); + + list($group_id, $is_moderator) = $db->fetch_row($result); + + if ($pun_user['g_mod_edit_users'] == '0' || $group_id == PUN_ADMIN || $is_moderator == '1') + message($lang_common['No permission']); + } + } + + if (isset($_GET['key'])) + { + $key = $_GET['key']; + + $result = $db->query('SELECT activate_string, activate_key FROM '.$db->prefix.'users WHERE id='.$id) or error('Unable to fetch activation data', __FILE__, __LINE__, $db->error()); + list($new_email, $new_email_key) = $db->fetch_row($result); + + if ($key == '' || $key != $new_email_key) + message($lang_profile['Email key bad'].' '.$pun_config['o_admin_email'].'.'); + else + { + $db->query('UPDATE '.$db->prefix.'users SET email=activate_string, activate_string=NULL, activate_key=NULL WHERE id='.$id) or error('Unable to update email address', __FILE__, __LINE__, $db->error()); + + message($lang_profile['Email updated'], true); + } + } + else if (isset($_POST['form_sent'])) + { + if (pun_hash($_POST['req_password']) !== $pun_user['password']) + message($lang_profile['Wrong pass']); + + require PUN_ROOT.'include/email.php'; + + // Validate the email address + $new_email = strtolower(trim($_POST['req_new_email'])); + if (!is_valid_email($new_email)) + message($lang_common['Invalid email']); + + // Check if it's a banned email address + if (is_banned_email($new_email)) + { + if ($pun_config['p_allow_banned_email'] == '0') + message($lang_prof_reg['Banned email']); + else if ($pun_config['o_mailing_list'] != '') + { + $mail_subject = $lang_common['Banned email notification']; + $mail_message = sprintf($lang_common['Banned email change message'], $pun_user['username'], $new_email)."\n"; + $mail_message .= sprintf($lang_common['User profile'], $pun_config['o_base_url'].'/profile.php?id='.$id)."\n"; + $mail_message .= "\n".'--'."\n".$lang_common['Email signature']; + + pun_mail($pun_config['o_mailing_list'], $mail_subject, $mail_message); + } + } + + // Check if someone else already has registered with that email address + $result = $db->query('SELECT id, username FROM '.$db->prefix.'users WHERE email=\''.$db->escape($new_email).'\'') or error('Unable to fetch user info', __FILE__, __LINE__, $db->error()); + if ($db->num_rows($result)) + { + if ($pun_config['p_allow_dupe_email'] == '0') + message($lang_prof_reg['Dupe email']); + else if ($pun_config['o_mailing_list'] != '') + { + while ($cur_dupe = $db->fetch_assoc($result)) + $dupe_list[] = $cur_dupe['username']; + + $mail_subject = $lang_common['Duplicate email notification']; + $mail_message = sprintf($lang_common['Duplicate email change message'], $pun_user['username'], implode(', ', $dupe_list))."\n"; + $mail_message .= sprintf($lang_common['User profile'], $pun_config['o_base_url'].'/profile.php?id='.$id)."\n"; + $mail_message .= "\n".'--'."\n".$lang_common['Email signature']; + + pun_mail($pun_config['o_mailing_list'], $mail_subject, $mail_message); + } + } + + + $new_email_key = random_pass(8); + + $db->query('UPDATE '.$db->prefix.'users SET activate_string=\''.$db->escape($new_email).'\', activate_key=\''.$new_email_key.'\' WHERE id='.$id) or error('Unable to update activation data', __FILE__, __LINE__, $db->error()); + + // Load the "activate email" template + $mail_tpl = trim(file_get_contents(PUN_ROOT.'lang/'.$pun_user['language'].'/mail_templates/activate_email.tpl')); + + // The first row contains the subject + $first_crlf = strpos($mail_tpl, "\n"); + $mail_subject = trim(substr($mail_tpl, 8, $first_crlf-8)); + $mail_message = trim(substr($mail_tpl, $first_crlf)); + + $mail_message = str_replace('', $pun_user['username'], $mail_message); + $mail_message = str_replace('', $pun_config['o_base_url'], $mail_message); + $mail_message = str_replace('', $pun_config['o_base_url'].'/profile.php?action=change_email&id='.$id.'&key='.$new_email_key, $mail_message); + $mail_message = str_replace('', $pun_config['o_board_title'].' '.$lang_common['Mailer'], $mail_message); + + pun_mail($new_email, $mail_subject, $mail_message); + + message($lang_profile['Activate email sent'].' '.$pun_config['o_admin_email'].'.', true); + } + + $page_title = array(pun_htmlspecialchars($pun_config['o_board_title']), $lang_common['Profile'], $lang_profile['Change email']); + $required_fields = array('req_new_email' => $lang_profile['New email'], 'req_password' => $lang_common['Password']); + $focus_element = array('change_email', 'req_new_email'); + define('PUN_ACTIVE_PAGE', 'profile'); + require PUN_ROOT.'header.php'; + +?> +
    +

    +
    +
    +
    +
    + +
    + + + +

    +
    +
    +
    +

    +
    +
    +
    + $pun_config['o_avatars_size']) + message($lang_profile['Too large'].' '.forum_number_format($pun_config['o_avatars_size']).' '.$lang_profile['bytes'].'.'); + + // Move the file to the avatar directory. We do this before checking the width/height to circumvent open_basedir restrictions + if (!@move_uploaded_file($uploaded_file['tmp_name'], $pun_config['o_avatars_dir'].'/'.$id.'.tmp')) + message($lang_profile['Move failed'].' '.$pun_config['o_admin_email'].'.'); + + list($width, $height, $type,) = @getimagesize($pun_config['o_avatars_dir'].'/'.$id.'.tmp'); + + // Determine type + $extension = null; + if ($type == IMAGETYPE_GIF) + $extension = '.gif'; + else if ($type == IMAGETYPE_JPEG) + $extension = '.jpg'; + else if ($type == IMAGETYPE_PNG) + $extension = '.png'; + else + { + // Invalid type + @unlink($pun_config['o_avatars_dir'].'/'.$id.'.tmp'); + message($lang_profile['Bad type']); + } + + // Now check the width/height + if (empty($width) || empty($height) || $width > $pun_config['o_avatars_width'] || $height > $pun_config['o_avatars_height']) + { + @unlink($pun_config['o_avatars_dir'].'/'.$id.'.tmp'); + message($lang_profile['Too wide or high'].' '.$pun_config['o_avatars_width'].'x'.$pun_config['o_avatars_height'].' '.$lang_profile['pixels'].'.'); + } + + // Delete any old avatars and put the new one in place + delete_avatar($id); + @rename($pun_config['o_avatars_dir'].'/'.$id.'.tmp', $pun_config['o_avatars_dir'].'/'.$id.$extension); + @chmod($pun_config['o_avatars_dir'].'/'.$id.$extension, 0644); + } + else + message($lang_profile['Unknown failure']); + + redirect('profile.php?section=personality&id='.$id, $lang_profile['Avatar upload redirect']); + } + + $page_title = array(pun_htmlspecialchars($pun_config['o_board_title']), $lang_common['Profile'], $lang_profile['Upload avatar']); + $required_fields = array('req_file' => $lang_profile['File']); + $focus_element = array('upload_avatar', 'req_file'); + define('PUN_ACTIVE_PAGE', 'profile'); + require PUN_ROOT.'header.php'; + +?> +
    +

    +
    +
    +
    +
    + +
    + + + +

    KB).

    +
    +
    +
    +

    +
    +
    +
    + PUN_ADMIN) + message($lang_common['No permission']); + + confirm_referrer('profile.php'); + + $new_group_id = intval($_POST['group_id']); + + $db->query('UPDATE '.$db->prefix.'users SET group_id='.$new_group_id.' WHERE id='.$id) or error('Unable to change user group', __FILE__, __LINE__, $db->error()); + + $result = $db->query('SELECT g_moderator FROM '.$db->prefix.'groups WHERE g_id='.$new_group_id) or error('Unable to fetch group', __FILE__, __LINE__, $db->error()); + $new_group_mod = $db->result($result); + + // If the user was a moderator or an administrator, we remove him/her from the moderator list in all forums as well + if ($new_group_id != PUN_ADMIN && $new_group_mod != '1') + { + $result = $db->query('SELECT id, moderators FROM '.$db->prefix.'forums') or error('Unable to fetch forum list', __FILE__, __LINE__, $db->error()); + + while ($cur_forum = $db->fetch_assoc($result)) + { + $cur_moderators = ($cur_forum['moderators'] != '') ? unserialize($cur_forum['moderators']) : array(); + + if (in_array($id, $cur_moderators)) + { + $username = array_search($id, $cur_moderators); + unset($cur_moderators[$username]); + $cur_moderators = (!empty($cur_moderators)) ? '\''.$db->escape(serialize($cur_moderators)).'\'' : 'NULL'; + + $db->query('UPDATE '.$db->prefix.'forums SET moderators='.$cur_moderators.' WHERE id='.$cur_forum['id']) or error('Unable to update forum', __FILE__, __LINE__, $db->error()); + } + } + } + + redirect('profile.php?section=admin&id='.$id, $lang_profile['Group membership redirect']); +} + + +else if (isset($_POST['update_forums'])) +{ + if ($pun_user['g_id'] > PUN_ADMIN) + message($lang_common['No permission']); + + confirm_referrer('profile.php'); + + // Get the username of the user we are processing + $result = $db->query('SELECT username FROM '.$db->prefix.'users WHERE id='.$id) or error('Unable to fetch user info', __FILE__, __LINE__, $db->error()); + $username = $db->result($result); + + $moderator_in = (isset($_POST['moderator_in'])) ? array_keys($_POST['moderator_in']) : array(); + + // Loop through all forums + $result = $db->query('SELECT id, moderators FROM '.$db->prefix.'forums') or error('Unable to fetch forum list', __FILE__, __LINE__, $db->error()); + + while ($cur_forum = $db->fetch_assoc($result)) + { + $cur_moderators = ($cur_forum['moderators'] != '') ? unserialize($cur_forum['moderators']) : array(); + // If the user should have moderator access (and he/she doesn't already have it) + if (in_array($cur_forum['id'], $moderator_in) && !in_array($id, $cur_moderators)) + { + $cur_moderators[$username] = $id; + uksort($cur_moderators, 'utf8_strcasecmp'); + + $db->query('UPDATE '.$db->prefix.'forums SET moderators=\''.$db->escape(serialize($cur_moderators)).'\' WHERE id='.$cur_forum['id']) or error('Unable to update forum', __FILE__, __LINE__, $db->error()); + } + // If the user shouldn't have moderator access (and he/she already has it) + else if (!in_array($cur_forum['id'], $moderator_in) && in_array($id, $cur_moderators)) + { + unset($cur_moderators[$username]); + $cur_moderators = (!empty($cur_moderators)) ? '\''.$db->escape(serialize($cur_moderators)).'\'' : 'NULL'; + + $db->query('UPDATE '.$db->prefix.'forums SET moderators='.$cur_moderators.' WHERE id='.$cur_forum['id']) or error('Unable to update forum', __FILE__, __LINE__, $db->error()); + } + } + + redirect('profile.php?section=admin&id='.$id, $lang_profile['Update forums redirect']); +} + + +else if (isset($_POST['ban'])) +{ + if ($pun_user['g_id'] != PUN_ADMIN && ($pun_user['g_moderator'] != '1' || $pun_user['g_mod_ban_users'] == '0')) + message($lang_common['No permission']); + + redirect('admin_bans.php?add_ban='.$id, $lang_profile['Ban redirect']); +} + + +else if (isset($_POST['delete_user']) || isset($_POST['delete_user_comply'])) +{ + if ($pun_user['g_id'] > PUN_ADMIN) + message($lang_common['No permission']); + + confirm_referrer('profile.php'); + + // Get the username and group of the user we are deleting + $result = $db->query('SELECT group_id, username FROM '.$db->prefix.'users WHERE id='.$id) or error('Unable to fetch user info', __FILE__, __LINE__, $db->error()); + list($group_id, $username) = $db->fetch_row($result); + + if ($group_id == PUN_ADMIN) + message($lang_profile['No delete admin message']); + + if (isset($_POST['delete_user_comply'])) + { + // If the user is a moderator or an administrator, we remove him/her from the moderator list in all forums as well + $result = $db->query('SELECT g_moderator FROM '.$db->prefix.'groups WHERE g_id='.$group_id) or error('Unable to fetch group', __FILE__, __LINE__, $db->error()); + $group_mod = $db->result($result); + + if ($group_id == PUN_ADMIN || $group_mod == '1') + { + $result = $db->query('SELECT id, moderators FROM '.$db->prefix.'forums') or error('Unable to fetch forum list', __FILE__, __LINE__, $db->error()); + + while ($cur_forum = $db->fetch_assoc($result)) + { + $cur_moderators = ($cur_forum['moderators'] != '') ? unserialize($cur_forum['moderators']) : array(); + + if (in_array($id, $cur_moderators)) + { + unset($cur_moderators[$username]); + $cur_moderators = (!empty($cur_moderators)) ? '\''.$db->escape(serialize($cur_moderators)).'\'' : 'NULL'; + + $db->query('UPDATE '.$db->prefix.'forums SET moderators='.$cur_moderators.' WHERE id='.$cur_forum['id']) or error('Unable to update forum', __FILE__, __LINE__, $db->error()); + } + } + } + + // Delete any subscriptions + $db->query('DELETE FROM '.$db->prefix.'subscriptions WHERE user_id='.$id) or error('Unable to delete subscriptions', __FILE__, __LINE__, $db->error()); + + // Remove him/her from the online list (if they happen to be logged in) + $db->query('DELETE FROM '.$db->prefix.'online WHERE user_id='.$id) or error('Unable to remove user from online list', __FILE__, __LINE__, $db->error()); + + // Should we delete all posts made by this user? + if (isset($_POST['delete_posts'])) + { + require PUN_ROOT.'include/search_idx.php'; + @set_time_limit(0); + + // Find all posts made by this user + $result = $db->query('SELECT p.id, p.topic_id, t.forum_id FROM '.$db->prefix.'posts AS p INNER JOIN '.$db->prefix.'topics AS t ON t.id=p.topic_id INNER JOIN '.$db->prefix.'forums AS f ON f.id=t.forum_id WHERE p.poster_id='.$id) or error('Unable to fetch posts', __FILE__, __LINE__, $db->error()); + if ($db->num_rows($result)) + { + while ($cur_post = $db->fetch_assoc($result)) + { + // Determine whether this post is the "topic post" or not + $result2 = $db->query('SELECT id FROM '.$db->prefix.'posts WHERE topic_id='.$cur_post['topic_id'].' ORDER BY posted LIMIT 1') or error('Unable to fetch post info', __FILE__, __LINE__, $db->error()); + + if ($db->result($result2) == $cur_post['id']) + delete_topic($cur_post['topic_id']); + else + delete_post($cur_post['id'], $cur_post['topic_id']); + + update_forum($cur_post['forum_id']); + } + } + } + else + // Set all his/her posts to guest + $db->query('UPDATE '.$db->prefix.'posts SET poster_id=1 WHERE poster_id='.$id) or error('Unable to update posts', __FILE__, __LINE__, $db->error()); + + // Delete the user + $db->query('DELETE FROM '.$db->prefix.'users WHERE id='.$id) or error('Unable to delete user', __FILE__, __LINE__, $db->error()); + + // Delete user avatar + delete_avatar($id); + + redirect('index.php', $lang_profile['User delete redirect']); + } + + $page_title = array(pun_htmlspecialchars($pun_config['o_board_title']), $lang_common['Profile'], $lang_profile['Confirm delete user']); + define('PUN_ACTIVE_PAGE', 'profile'); + require PUN_ROOT.'header.php'; + +?> +
    +

    +
    +
    +
    +
    + +
    +

    '.pun_htmlspecialchars($username).'.' ?>

    +
    + +
    +

    +
    +
    +
    +

    +
    +
    +
    +query('SELECT u.group_id, g.g_moderator FROM '.$db->prefix.'users AS u INNER JOIN '.$db->prefix.'groups AS g ON (g.g_id=u.group_id) WHERE u.id='.$id) or error('Unable to fetch user info', __FILE__, __LINE__, $db->error()); + if (!$db->num_rows($result)) + message($lang_common['Bad request']); + + list($group_id, $is_moderator) = $db->fetch_row($result); + + if ($pun_user['id'] != $id && + (!$pun_user['is_admmod'] || + ($pun_user['g_moderator'] == '1' && $pun_user['g_mod_edit_users'] == '0') || + ($pun_user['g_moderator'] == '1' && $is_moderator))) + message($lang_common['No permission']); + + if ($pun_user['is_admmod']) + confirm_referrer('profile.php'); + + $username_updated = false; + + // Validate input depending on section + switch ($section) + { + case 'essentials': + { + $form = array( + 'timezone' => floatval($_POST['form']['timezone']), + 'dst' => isset($_POST['form']['dst']) ? '1' : '0', + 'time_format' => intval($_POST['form']['time_format']), + 'date_format' => intval($_POST['form']['date_format']), + ); + + // Make sure we got a valid language string + if (isset($_POST['form']['language'])) + { + $form['language'] = preg_replace('#[\.\\\/]#', '', pun_trim($_POST['form']['language'])); + if (!file_exists(PUN_ROOT.'lang/'.$form['language'].'/common.php')) + message($lang_common['Bad request']); + } + + if ($pun_user['is_admmod']) + { + $form['admin_note'] = pun_trim($_POST['admin_note']); + + // Are we allowed to change usernames? + if ($pun_user['g_id'] == PUN_ADMIN || ($pun_user['g_moderator'] == '1' && $pun_user['g_mod_rename_users'] == '1')) + { + $form['username'] = pun_trim($_POST['req_username']); + $old_username = pun_trim($_POST['old_username']); + + // Check username + require PUN_ROOT.'lang/'.$pun_user['language'].'/register.php'; + + $errors = array(); + check_username($form['username'], $id); + if (!empty($errors)) + message($errors[0]); + + if ($form['username'] != $old_username) + $username_updated = true; + } + + // We only allow administrators to update the post count + if ($pun_user['g_id'] == PUN_ADMIN) + $form['num_posts'] = intval($_POST['num_posts']); + } + + if ($pun_config['o_regs_verify'] == '0' || $pun_user['is_admmod']) + { + require PUN_ROOT.'include/email.php'; + + // Validate the email address + $form['email'] = strtolower(trim($_POST['req_email'])); + if (!is_valid_email($form['email'])) + message($lang_common['Invalid email']); + } + + break; + } + + case 'personal': + { + $form = array( + 'realname' => pun_trim($_POST['form']['realname']), + 'url' => pun_trim($_POST['form']['url']), + 'location' => pun_trim($_POST['form']['location']), + ); + + // Add http:// if the URL doesn't contain it already (while allowing https://, too) + if ($form['url'] != '' && !preg_match('#^https?://#i', $form['url'])) + $form['url'] = 'http://'.$form['url']; + + if ($pun_user['g_id'] == PUN_ADMIN) + $form['title'] = pun_trim($_POST['title']); + else if ($pun_user['g_set_title'] == '1') + { + $form['title'] = pun_trim($_POST['title']); + + if ($form['title'] != '') + { + // A list of words that the title may not contain + // If the language is English, there will be some duplicates, but it's not the end of the world + $forbidden = array('member', 'moderator', 'administrator', 'banned', 'guest', utf8_strtolower($lang_common['Member']), utf8_strtolower($lang_common['Moderator']), utf8_strtolower($lang_common['Administrator']), utf8_strtolower($lang_common['Banned']), utf8_strtolower($lang_common['Guest'])); + + if (in_array(utf8_strtolower($form['title']), $forbidden)) + message($lang_profile['Forbidden title']); + } + } + + break; + } + + case 'messaging': + { + $form = array( + 'jabber' => pun_trim($_POST['form']['jabber']), + 'icq' => pun_trim($_POST['form']['icq']), + 'msn' => pun_trim($_POST['form']['msn']), + 'aim' => pun_trim($_POST['form']['aim']), + 'yahoo' => pun_trim($_POST['form']['yahoo']), + ); + + // If the ICQ UIN contains anything other than digits it's invalid + if (preg_match('/[^0-9]/', $form['icq'])) + message($lang_prof_reg['Bad ICQ']); + + break; + } + + case 'personality': + { + $form = array(); + + // Clean up signature from POST + if ($pun_config['o_signatures'] == '1') + { + $form['signature'] = pun_linebreaks(pun_trim($_POST['signature'])); + + // Validate signature + if (pun_strlen($form['signature']) > $pun_config['p_sig_length']) + message($lang_prof_reg['Sig too long'].' '.$pun_config['p_sig_length'].' '.$lang_prof_reg['characters'].'.'); + else if (substr_count($form['signature'], "\n") > ($pun_config['p_sig_lines']-1)) + message($lang_prof_reg['Sig too many lines'].' '.$pun_config['p_sig_lines'].' '.$lang_prof_reg['lines'].'.'); + else if ($form['signature'] && $pun_config['p_sig_all_caps'] == '0' && is_all_uppercase($form['signature']) && !$pun_user['is_admmod']) + $form['signature'] = utf8_ucwords(utf8_strtolower($form['signature'])); + + // Validate BBCode syntax + if ($pun_config['p_sig_bbcode'] == '1') + { + require PUN_ROOT.'include/parser.php'; + + $errors = array(); + + $form['signature'] = preparse_bbcode($form['signature'], $errors, true); + + if(count($errors) > 0) + message('
    • '.implode('
    • ', $errors).'
    '); + } + } + + break; + } + + case 'display': + { + $form = array( + 'disp_topics' => pun_trim($_POST['form']['disp_topics']), + 'disp_posts' => pun_trim($_POST['form']['disp_posts']), + 'show_smilies' => isset($_POST['form']['show_smilies']) ? '1' : '0', + 'show_img' => isset($_POST['form']['show_img']) ? '1' : '0', + 'show_img_sig' => isset($_POST['form']['show_img_sig']) ? '1' : '0', + 'show_avatars' => isset($_POST['form']['show_avatars']) ? '1' : '0', + 'show_sig' => isset($_POST['form']['show_sig']) ? '1' : '0', + ); + + if ($form['disp_topics'] != '') + { + $form['disp_topics'] = intval($form['disp_topics']); + if ($form['disp_topics'] < 3) + $form['disp_topics'] = 3; + else if ($form['disp_topics'] > 75) + $form['disp_topics'] = 75; + } + + if ($form['disp_posts'] != '') + { + $form['disp_posts'] = intval($form['disp_posts']); + if ($form['disp_posts'] < 3) + $form['disp_posts'] = 3; + else if ($form['disp_posts'] > 75) + $form['disp_posts'] = 75; + } + + // Make sure we got a valid style string + if (isset($_POST['form']['style'])) + { + $form['style'] = preg_replace('#[\.\\\/]#', '', pun_trim($_POST['form']['style'])); + if (!file_exists(PUN_ROOT.'style/'.$form['style'].'.css')) + message($lang_common['Bad request']); + } + + break; + } + + case 'privacy': + { + $form = array( + 'email_setting' => intval($_POST['form']['email_setting']), + 'notify_with_post' => isset($_POST['form']['notify_with_post']) ? '1' : '0', + 'auto_notify' => isset($_POST['form']['auto_notify']) ? '1' : '0', + ); + + if ($form['email_setting'] < 0 || $form['email_setting'] > 2) + $form['email_setting'] = $pun_config['o_default_email_setting']; + + break; + } + + default: + message($lang_common['Bad request']); + } + + + // Single quotes around non-empty values and NULL for empty values + $temp = array(); + foreach ($form as $key => $input) + { + $value = ($input !== '') ? '\''.$db->escape($input).'\'' : 'NULL'; + + $temp[] = $key.'='.$value; + } + + if (empty($temp)) + message($lang_common['Bad request']); + + + $db->query('UPDATE '.$db->prefix.'users SET '.implode(',', $temp).' WHERE id='.$id) or error('Unable to update profile', __FILE__, __LINE__, $db->error()); + + // If we changed the username we have to update some stuff + if ($username_updated) + { + $db->query('UPDATE '.$db->prefix.'posts SET poster=\''.$db->escape($form['username']).'\' WHERE poster_id='.$id) or error('Unable to update posts', __FILE__, __LINE__, $db->error()); + $db->query('UPDATE '.$db->prefix.'posts SET edited_by=\''.$db->escape($form['username']).'\' WHERE edited_by=\''.$db->escape($old_username).'\'') or error('Unable to update posts', __FILE__, __LINE__, $db->error()); + $db->query('UPDATE '.$db->prefix.'topics SET poster=\''.$db->escape($form['username']).'\' WHERE poster=\''.$db->escape($old_username).'\'') or error('Unable to update topics', __FILE__, __LINE__, $db->error()); + $db->query('UPDATE '.$db->prefix.'topics SET last_poster=\''.$db->escape($form['username']).'\' WHERE last_poster=\''.$db->escape($old_username).'\'') or error('Unable to update topics', __FILE__, __LINE__, $db->error()); + $db->query('UPDATE '.$db->prefix.'forums SET last_poster=\''.$db->escape($form['username']).'\' WHERE last_poster=\''.$db->escape($old_username).'\'') or error('Unable to update forums', __FILE__, __LINE__, $db->error()); + $db->query('UPDATE '.$db->prefix.'online SET ident=\''.$db->escape($form['username']).'\' WHERE ident=\''.$db->escape($old_username).'\'') or error('Unable to update online list', __FILE__, __LINE__, $db->error()); + + // If the user is a moderator or an administrator we have to update the moderator lists + $result = $db->query('SELECT group_id FROM '.$db->prefix.'users WHERE id='.$id) or error('Unable to fetch user info', __FILE__, __LINE__, $db->error()); + $group_id = $db->result($result); + + $result = $db->query('SELECT g_moderator FROM '.$db->prefix.'groups WHERE g_id='.$group_id) or error('Unable to fetch group', __FILE__, __LINE__, $db->error()); + $group_mod = $db->result($result); + + if ($group_id == PUN_ADMIN || $group_mod == '1') + { + $result = $db->query('SELECT id, moderators FROM '.$db->prefix.'forums') or error('Unable to fetch forum list', __FILE__, __LINE__, $db->error()); + + while ($cur_forum = $db->fetch_assoc($result)) + { + $cur_moderators = ($cur_forum['moderators'] != '') ? unserialize($cur_forum['moderators']) : array(); + + if (in_array($id, $cur_moderators)) + { + unset($cur_moderators[$old_username]); + $cur_moderators[$form['username']] = $id; + uksort($cur_moderators, 'utf8_strcasecmp'); + + $db->query('UPDATE '.$db->prefix.'forums SET moderators=\''.$db->escape(serialize($cur_moderators)).'\' WHERE id='.$cur_forum['id']) or error('Unable to update forum', __FILE__, __LINE__, $db->error()); + } + } + } + } + + redirect('profile.php?section='.$section.'&id='.$id, $lang_profile['Profile redirect']); +} + + +$result = $db->query('SELECT u.username, u.email, u.title, u.realname, u.url, u.jabber, u.icq, u.msn, u.aim, u.yahoo, u.location, u.signature, u.disp_topics, u.disp_posts, u.email_setting, u.notify_with_post, u.auto_notify, u.show_smilies, u.show_img, u.show_img_sig, u.show_avatars, u.show_sig, u.timezone, u.dst, u.language, u.style, u.num_posts, u.last_post, u.registered, u.registration_ip, u.admin_note, u.date_format, u.time_format, g.g_id, g.g_user_title, g.g_moderator FROM '.$db->prefix.'users AS u LEFT JOIN '.$db->prefix.'groups AS g ON g.g_id=u.group_id WHERE u.id='.$id) or error('Unable to fetch user info', __FILE__, __LINE__, $db->error()); +if (!$db->num_rows($result)) + message($lang_common['Bad request']); + +$user = $db->fetch_assoc($result); + +$last_post = format_time($user['last_post']); + +if ($user['signature'] != '') +{ + require PUN_ROOT.'include/parser.php'; + $parsed_signature = parse_signature($user['signature']); +} + + +// View or edit? +if ($pun_user['id'] != $id && + (!$pun_user['is_admmod'] || + ($pun_user['g_moderator'] == '1' && $pun_user['g_mod_edit_users'] == '0') || + ($pun_user['g_moderator'] == '1' && $user['g_moderator'] == '1'))) +{ + if ($user['email_setting'] == '0' && !$pun_user['is_guest'] && $pun_user['g_send_email'] == '1') + $email_field = ''; + else if ($user['email_setting'] == '1' && !$pun_user['is_guest'] && $pun_user['g_send_email'] == '1') + $email_field = ''; + else + $email_field = $lang_profile['Private']; + + $user_title_field = get_title($user); + + if ($user['url'] != '') + { + $user['url'] = pun_htmlspecialchars($user['url']); + + if ($pun_config['o_censoring'] == '1') + $user['url'] = censor_words($user['url']); + + $url = ''.$user['url'].''; + } + else + $url = $lang_profile['Unknown']; + + if ($pun_config['o_avatars'] == '1') + { + $avatar_field = generate_avatar_markup($id); + if ($avatar_field == '') + $avatar_field = $lang_profile['No avatar']; + } + + $posts_field = ''; + if ($pun_config['o_show_post_count'] == '1' || $pun_user['is_admmod']) + $posts_field = forum_number_format($user['num_posts']); + if ($pun_user['g_search'] == '1') + $posts_field .= (($posts_field != '') ? ' - ' : '').''.$lang_profile['Show posts'].''; + + $page_title = array(pun_htmlspecialchars($pun_config['o_board_title']), sprintf($lang_profile['Users profile'], pun_htmlspecialchars($user['username']))); + define('PUN_ALLOW_INDEX', 1); + define('PUN_ACTIVE_PAGE', 'index'); + require PUN_ROOT.'header.php'; + +?> +
    +

    +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    '.$parsed_signature.'
    ' : $lang_profile['No sig']; ?> + +
    +
    + +
    +
    +
    + +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + +'."\n"; + else + $username_field = '

    '.sprintf($lang_profile['Username info'], pun_htmlspecialchars($user['username'])).'

    '."\n"; + + $email_field = '

    '."\n"; + } + else + { + $username_field = '

    '.$lang_common['Username'].': '.pun_htmlspecialchars($user['username']).'

    '."\n"; + + if ($pun_config['o_regs_verify'] == '1') + $email_field = '

    '.sprintf($lang_profile['Email info'], $user['email'].' - '.$lang_profile['Change email'].'').'

    '."\n"; + else + $email_field = ''."\n"; + } + + $posts_field = ''; + if ($pun_user['g_id'] == PUN_ADMIN) + $posts_field = '

    '.$lang_profile['Show posts'].'

    '."\n"; + else if ($pun_config['o_show_post_count'] == '1' || $pun_user['is_admmod']) + $posts_field = '

    '.sprintf($lang_profile['Posts info'], forum_number_format($user['num_posts']).($pun_user['g_search'] == '1' ? ' - '.$lang_profile['Show posts'].'' : '')).'

    '."\n"; + else if ($pun_user['g_search'] == '1') + $posts_field = '

    '.$lang_profile['Show posts'].'

    '."\n"; + + + $page_title = array(pun_htmlspecialchars($pun_config['o_board_title']), $lang_common['Profile'], $lang_profile['Section essentials']); + $required_fields = array('req_username' => $lang_common['Username'], 'req_email' => $lang_common['Email']); + define('PUN_ACTIVE_PAGE', 'profile'); + require PUN_ROOT.'header.php'; + + generate_profile_menu('essentials'); + +?> +
    +

    +
    +
    +
    +
    + +
    + + +

    +
    +
    +
    +
    +
    + +
    + +
    +
    +
    +
    +
    + +
    +

    + +
    + +
    + + + + 1) + { + +?> + + +
    +
    +
    +
    +
    + +
    +

    '.pun_htmlspecialchars($user['registration_ip']).')' : '')) ?>

    +

    + + +
    +
    +
    +

    +
    +
    +
    +'.$lang_common['Title'].' ('.$lang_profile['Leave blank'].')

    '."\n"; + + $page_title = array(pun_htmlspecialchars($pun_config['o_board_title']), $lang_common['Profile'], $lang_profile['Section personal']); + define('PUN_ACTIVE_PAGE', 'profile'); + require PUN_ROOT.'header.php'; + + generate_profile_menu('personal'); + +?> +
    +

    +
    +
    +
    +
    + +
    + + + + + +
    +
    +
    +

    +
    +
    +
    + +
    +

    +
    +
    +
    +
    + +
    + + + + + + +
    +
    +
    +

    +
    +
    +
    +'.$lang_profile['Change avatar'].''; + + $user_avatar = generate_avatar_markup($id); + if ($user_avatar) + $avatar_field .= ' '.$lang_profile['Delete avatar'].''; + else + $avatar_field = ''.$lang_profile['Upload avatar'].''; + + if ($user['signature'] != '') + $signature_preview = '

    '.$lang_profile['Sig preview'].'

    '."\n\t\t\t\t\t\t\t".'
    '."\n\t\t\t\t\t\t\t\t".'
    '."\n\t\t\t\t\t\t\t\t".$parsed_signature."\n\t\t\t\t\t\t\t".'
    '."\n"; + else + $signature_preview = '

    '.$lang_profile['No sig'].'

    '."\n"; + + $page_title = array(pun_htmlspecialchars($pun_config['o_board_title']), $lang_common['Profile'], $lang_profile['Section personality']); + define('PUN_ACTIVE_PAGE', 'profile'); + require PUN_ROOT.'header.php'; + + generate_profile_menu('personality'); + + +?> +
    +

    +
    +
    +
    +
    +
    + +
    +
    +

    +

    +
    +
    +
    +
    +
    + +
    +

    +
    + +
    + + +
    +
    +
    +

    +
    +
    +
    + +
    +

    +
    +
    +
    +
    '."\n"; + else if (count($styles) > 1) + { + +?> +
    +
    + +
    + +
    +
    +
    + + +
    +
    + +
    +

    +
    + + + + + + +
    +
    +
    +
    + +
    +
    + +
    + + +

    +
    +
    +
    +

    + +
    + + +
    +

    +
    +
    +
    +
    + +
    + +

    +
    + + + +
    +
    +
    +
    +
    +
    + +
    +
    + + +
    +
    +
    +
    +

    +
    +
    +
    + +
    +

    +
    +
    +
    + +
    + + +
    +

    +
    +
    +
    + + +
    + + +
    + +
    +
    +
    + + +
    + +
    +
    +
    + +
    +
    + +
    +

    +query('SELECT c.id AS cid, c.cat_name, f.id AS fid, f.forum_name, f.moderators FROM '.$db->prefix.'categories AS c INNER JOIN '.$db->prefix.'forums AS f ON c.id=f.cat_id WHERE f.redirect_url IS NULL ORDER BY c.disp_position, c.id, f.disp_position') or error('Unable to fetch category/forum list', __FILE__, __LINE__, $db->error()); + + $cur_category = 0; + while ($cur_forum = $db->fetch_assoc($result)) + { + if ($cur_forum['cid'] != $cur_category) // A new category since last iteration? + { + if ($cur_category) + echo "\n\t\t\t\t\t\t\t\t".'
    '; + + if ($cur_category != 0) + echo "\n\t\t\t\t\t\t\t".'
    '."\n"; + + echo "\t\t\t\t\t\t\t".'
    '."\n\t\t\t\t\t\t\t\t".'

    '.$cur_forum['cat_name'].'

    '."\n\t\t\t\t\t\t\t\t".'
    '; + $cur_category = $cur_forum['cid']; + } + + $moderators = ($cur_forum['moderators'] != '') ? unserialize($cur_forum['moderators']) : array(); + + echo "\n\t\t\t\t\t\t\t\t\t".''."\n"; + } + +?> +
    +
    +
    +
    + + + + + + + +
    + + +
    +

    +
    +
    +
    +
    + +
    +
    +
    +
    +
    +

    +
    +
    +
    +query('SELECT 1 FROM '.$db->prefix.'users WHERE registration_ip=\''.get_remote_address().'\' AND registered>'.(time() - 3600)) or error('Unable to fetch user info', __FILE__, __LINE__, $db->error()); + + if ($db->num_rows($result)) + message($lang_register['Registration flood']); + + + $username = pun_trim($_POST['req_user']); + $email1 = strtolower(trim($_POST['req_email1'])); + + if ($pun_config['o_regs_verify'] == '1') + { + $email2 = strtolower(trim($_POST['req_email2'])); + + $password1 = random_pass(8); + $password2 = $password1; + } + else + { + $password1 = pun_trim($_POST['req_password1']); + $password2 = pun_trim($_POST['req_password2']); + } + + // Validate username and passwords + check_username($username); + + if (pun_strlen($password1) < 4) + $errors[] = $lang_prof_reg['Pass too short']; + else if ($password1 != $password2) + $errors[] = $lang_prof_reg['Pass not match']; + + // Validate email + require PUN_ROOT.'include/email.php'; + + if (!is_valid_email($email1)) + $errors[] = $lang_common['Invalid email']; + else if ($pun_config['o_regs_verify'] == '1' && $email1 != $email2) + $errors[] = $lang_register['Email not match']; + + // Check if it's a banned email address + if (is_banned_email($email1)) + { + if ($pun_config['p_allow_banned_email'] == '0') + $errors[] = $lang_prof_reg['Banned email']; + + $banned_email = true; // Used later when we send an alert email + } + else + $banned_email = false; + + // Check if someone else already has registered with that email address + $dupe_list = array(); + + $result = $db->query('SELECT username FROM '.$db->prefix.'users WHERE email=\''.$db->escape($email1).'\'') or error('Unable to fetch user info', __FILE__, __LINE__, $db->error()); + if ($db->num_rows($result)) + { + if ($pun_config['p_allow_dupe_email'] == '0') + $errors[] = $lang_prof_reg['Dupe email']; + + while ($cur_dupe = $db->fetch_assoc($result)) + $dupe_list[] = $cur_dupe['username']; + } + + // Make sure we got a valid language string + if (isset($_POST['language'])) + { + $language = preg_replace('#[\.\\\/]#', '', $_POST['language']); + if (!file_exists(PUN_ROOT.'lang/'.$language.'/common.php')) + message($lang_common['Bad request']); + } + else + $language = $pun_config['o_default_lang']; + + $timezone = round($_POST['timezone'], 1); + + $dst = isset($_POST['dst']) ? '1' : '0'; + + $email_setting = intval($_POST['email_setting']); + if ($email_setting < 0 || $email_setting > 2) + $email_setting = $pun_config['o_default_email_setting']; + + // Did everything go according to plan? + if (empty($errors)) + { + // Insert the new user into the database. We do this now to get the last inserted ID for later use + $now = time(); + + $intial_group_id = ($pun_config['o_regs_verify'] == '0') ? $pun_config['o_default_user_group'] : PUN_UNVERIFIED; + $password_hash = pun_hash($password1); + + // Add the user + $db->query('INSERT INTO '.$db->prefix.'users (username, group_id, password, email, email_setting, timezone, dst, language, style, registered, registration_ip, last_visit) VALUES(\''.$db->escape($username).'\', '.$intial_group_id.', \''.$password_hash.'\', \''.$db->escape($email1).'\', '.$email_setting.', '.$timezone.' , '.$dst.', \''.$db->escape($language).'\', \''.$pun_config['o_default_style'].'\', '.$now.', \''.get_remote_address().'\', '.$now.')') or error('Unable to create user', __FILE__, __LINE__, $db->error()); + $new_uid = $db->insert_id(); + + // If the mailing list isn't empty, we may need to send out some alerts + if ($pun_config['o_mailing_list'] != '') + { + // If we previously found out that the email was banned + if ($banned_email) + { + $mail_subject = $lang_common['Banned email notification']; + $mail_message = sprintf($lang_common['Banned email register message'], $username, $email1)."\n"; + $mail_message .= sprintf($lang_common['User profile'], $pun_config['o_base_url'].'/profile.php?id='.$new_uid)."\n"; + $mail_message .= "\n".'--'."\n".$lang_common['Email signature']; + + pun_mail($pun_config['o_mailing_list'], $mail_subject, $mail_message); + } + + // If we previously found out that the email was a dupe + if (!empty($dupe_list)) + { + $mail_subject = $lang_common['Duplicate email notification']; + $mail_message = sprintf($lang_common['Duplicate email register message'], $username, implode(', ', $dupe_list))."\n"; + $mail_message .= sprintf($lang_common['User profile'], $pun_config['o_base_url'].'/profile.php?id='.$new_uid)."\n"; + $mail_message .= "\n".'--'."\n".$lang_common['Email signature']; + + pun_mail($pun_config['o_mailing_list'], $mail_subject, $mail_message); + } + + // Should we alert people on the admin mailing list that a new user has registered? + if ($pun_config['o_regs_report'] == '1') + { + $mail_subject = $lang_common['New user notification']; + $mail_message = sprintf($lang_common['New user message'], $username, $pun_config['o_base_url'].'/')."\n"; + $mail_message .= sprintf($lang_common['User profile'], $pun_config['o_base_url'].'/profile.php?id='.$new_uid)."\n"; + $mail_message .= "\n".'--'."\n".$lang_common['Email signature']; + + pun_mail($pun_config['o_mailing_list'], $mail_subject, $mail_message); + } + } + + // Must the user verify the registration or do we log him/her in right now? + if ($pun_config['o_regs_verify'] == '1') + { + // Load the "welcome" template + $mail_tpl = trim(file_get_contents(PUN_ROOT.'lang/'.$pun_user['language'].'/mail_templates/welcome.tpl')); + + // The first row contains the subject + $first_crlf = strpos($mail_tpl, "\n"); + $mail_subject = trim(substr($mail_tpl, 8, $first_crlf-8)); + $mail_message = trim(substr($mail_tpl, $first_crlf)); + + $mail_subject = str_replace('', $pun_config['o_board_title'], $mail_subject); + $mail_message = str_replace('', $pun_config['o_base_url'].'/', $mail_message); + $mail_message = str_replace('', $username, $mail_message); + $mail_message = str_replace('', $password1, $mail_message); + $mail_message = str_replace('', $pun_config['o_base_url'].'/login.php', $mail_message); + $mail_message = str_replace('', $pun_config['o_board_title'].' '.$lang_common['Mailer'], $mail_message); + + pun_mail($email1, $mail_subject, $mail_message); + + message($lang_register['Reg email'].' '.$pun_config['o_admin_email'].'.', true); + } + + pun_setcookie($new_uid, $password_hash, time() + $pun_config['o_timeout_visit']); + + redirect('index.php', $lang_register['Reg complete']); + } +} + + +$page_title = array(pun_htmlspecialchars($pun_config['o_board_title']), $lang_register['Register']); +$required_fields = array('req_user' => $lang_common['Username'], 'req_password1' => $lang_common['Password'], 'req_password2' => $lang_prof_reg['Confirm pass'], 'req_email1' => $lang_common['Email'], 'req_email2' => $lang_common['Email'].' 2'); +$focus_element = array('register', 'req_user'); +define('PUN_ACTIVE_PAGE', 'register'); +require PUN_ROOT.'header.php'; + +$timezone = isset($timezone) ? $timezone : $pun_config['o_default_timezone']; +$dst = isset($dst) ? $dst : $pun_config['o_default_dst']; +$email_setting = isset($email_setting) ? $email_setting : $pun_config['o_default_email_setting']; + +?> + +
    +

    +
    +
    +

    +
      +'.$cur_error.''."\n"; +?> +
    +
    +
    +
    + + +
    +

    +
    +
    +
    +
    +

    +

    +

    +
    +
    +
    +
    + +
    + + +
    +
    +
    +
    +
    + +
    + + +

    +
    +
    +
    +
    +
    + +
    +

    + + +
    +
    +
    +
    +
    + +
    +

    + +
    + +
    + 1) + { + +?> + + +
    +
    +
    +
    +
    + +
    +

    +
    + + + +
    +
    +
    +
    +

    +
    +
    +
    +query('SELECT search_data FROM '.$db->prefix.'search_cache WHERE id='.$search_id.' AND ident=\''.$db->escape($ident).'\'') or error('Unable to fetch search results', __FILE__, __LINE__, $db->error()); + if ($row = $db->fetch_assoc($result)) + { + $temp = unserialize($row['search_data']); + + $search_ids = unserialize($temp['search_ids']); + $num_hits = $temp['num_hits']; + $sort_by = $temp['sort_by']; + $sort_dir = $temp['sort_dir']; + $show_as = $temp['show_as']; + + unset($temp); + } + else + message($lang_search['No hits']); + } + else + { + $keyword_results = $author_results = array(); + + // Search a specific forum? + $forum_sql = ($forum != -1 || ($forum == -1 && $pun_config['o_search_all_forums'] == '0' && !$pun_user['is_admmod'])) ? ' AND t.forum_id = '.$forum : ''; + + if (!empty($author) || !empty($keywords)) + { + // Flood protection + if ($pun_user['last_search'] && (time() - $pun_user['last_search']) < $pun_user['g_search_flood'] && (time() - $pun_user['last_search']) >= 0) + message(sprintf($lang_search['Search flood'], $pun_user['g_search_flood'])); + + if (!$pun_user['is_guest']) + $db->query('UPDATE '.$db->prefix.'users SET last_search='.time().' WHERE id='.$pun_user['id']) or error('Unable to update user', __FILE__, __LINE__, $db->error()); + else + $db->query('UPDATE '.$db->prefix.'online SET last_search='.time().' WHERE ident=\''.$db->escape(get_remote_address()).'\'' ) or error('Unable to update user', __FILE__, __LINE__, $db->error()); + + switch ($sort_by) + { + case 1: + $sort_by_sql = ($show_as == 'topics') ? 't.poster' : 'p.poster'; + $sort_type = SORT_STRING; + break; + + case 2: + $sort_by_sql = 't.subject'; + $sort_type = SORT_STRING; + break; + + case 3: + $sort_by_sql = 't.forum_id'; + $sort_type = SORT_NUMERIC; + break; + + case 4: + $sort_by_sql = 't.last_post'; + $sort_type = SORT_NUMERIC; + break; + + default: + $sort_by_sql = ($show_as == 'topics') ? 't.last_post' : 'p.posted'; + $sort_type = SORT_NUMERIC; + break; + } + + // If it's a search for keywords + if ($keywords) + { + // split the keywords into words + $keywords_array = split_words($keywords, false); + + if (empty($keywords_array)) + message($lang_search['No hits']); + + // Should we search in message body or topic subject specifically? + $search_in_cond = ($search_in) ? (($search_in > 0) ? ' AND m.subject_match = 0' : ' AND m.subject_match = 1') : ''; + + $word_count = 0; + $match_type = 'and'; + + $sort_data = array(); + foreach ($keywords_array as $cur_word) + { + switch ($cur_word) + { + case 'and': + case 'or': + case 'not': + $match_type = $cur_word; + break; + + default: + { + if (is_cjk($cur_word)) + { + $where_cond = str_replace('*', '%', $cur_word); + $where_cond = ($search_in ? (($search_in > 0) ? 'p.message LIKE \'%'.$db->escape($where_cond).'%\'' : 't.subject LIKE \'%'.$db->escape($where_cond).'%\'') : 'p.message LIKE \'%'.$db->escape($where_cond).'%\' OR t.subject LIKE \'%'.$db->escape($where_cond).'%\''); + + $result = $db->query('SELECT p.id AS post_id, p.topic_id, '.$sort_by_sql.' AS sort_by FROM '.$db->prefix.'posts AS p INNER JOIN '.$db->prefix.'topics AS t ON t.id=p.topic_id LEFT JOIN '.$db->prefix.'forum_perms AS fp ON (fp.forum_id=t.forum_id AND fp.group_id='.$pun_user['g_id'].') WHERE ('.$where_cond.') AND (fp.read_forum IS NULL OR fp.read_forum=1)'.$forum_sql, true) or error('Unable to search for posts', __FILE__, __LINE__, $db->error()); + } + else + $result = $db->query('SELECT m.post_id, p.topic_id, '.$sort_by_sql.' AS sort_by FROM '.$db->prefix.'search_words AS w INNER JOIN '.$db->prefix.'search_matches AS m ON m.word_id = w.id INNER JOIN '.$db->prefix.'posts AS p ON p.id=m.post_id INNER JOIN '.$db->prefix.'topics AS t ON t.id=p.topic_id LEFT JOIN '.$db->prefix.'forum_perms AS fp ON (fp.forum_id=t.forum_id AND fp.group_id='.$pun_user['g_id'].') WHERE w.word LIKE \''.$db->escape(str_replace('*', '%', $cur_word)).'\''.$search_in_cond.' AND (fp.read_forum IS NULL OR fp.read_forum=1)'.$forum_sql, true) or error('Unable to search for posts', __FILE__, __LINE__, $db->error()); + + $row = array(); + while ($temp = $db->fetch_assoc($result)) + { + $row[$temp['post_id']] = $temp['topic_id']; + + if (!$word_count) + { + $keyword_results[$temp['post_id']] = $temp['topic_id']; + $sort_data[$temp['post_id']] = $temp['sort_by']; + } + else if ($match_type == 'or') + { + $keyword_results[$temp['post_id']] = $temp['topic_id']; + $sort_data[$temp['post_id']] = $temp['sort_by']; + } + else if ($match_type == 'not') + { + unset($keyword_results[$temp['post_id']]); + unset($sort_data[$temp['post_id']]); + } + } + + if ($match_type == 'and' && $word_count) + { + foreach ($keyword_results as $post_id => $topic_id) + { + if (!isset($row[$post_id])) + { + unset($keyword_results[$post_id]); + unset($sort_data[$post_id]); + } + } + } + + ++$word_count; + $db->free_result($result); + + break; + } + } + } + + // Sort the results - annoyingly array_multisort re-indexes arrays with numeric keys, so we need to split the keys out into a seperate array then combine them again after + $post_ids = array_keys($keyword_results); + $topic_ids = array_values($keyword_results); + + array_multisort(array_values($sort_data), $sort_dir == 'DESC' ? SORT_DESC : SORT_ASC, $sort_type, $post_ids, $topic_ids); + + // combine the arrays back into a key=>value array (array_combine is PHP5 only unfortunately) + $num_results = count($keyword_results); + $keyword_results = array(); + for ($i = 0;$i < $num_results;$i++) + $keyword_results[$post_ids[$i]] = $topic_ids[$i]; + + unset($sort_data, $post_ids, $topic_ids); + } + + // If it's a search for author name (and that author name isn't Guest) + if ($author && $author != 'guest' && $author != utf8_strtolower($lang_common['Guest'])) + { + switch ($db_type) + { + case 'pgsql': + $result = $db->query('SELECT id FROM '.$db->prefix.'users WHERE username ILIKE \''.$db->escape($author).'\'') or error('Unable to fetch users', __FILE__, __LINE__, $db->error()); + break; + + default: + $result = $db->query('SELECT id FROM '.$db->prefix.'users WHERE username LIKE \''.$db->escape($author).'\'') or error('Unable to fetch users', __FILE__, __LINE__, $db->error()); + break; + } + + if ($db->num_rows($result)) + { + $user_ids = array(); + while ($row = $db->fetch_row($result)) + $user_ids[] = $row[0]; + + $result = $db->query('SELECT p.id AS post_id, p.topic_id FROM '.$db->prefix.'posts AS p INNER JOIN '.$db->prefix.'topics AS t ON t.id=p.topic_id LEFT JOIN '.$db->prefix.'forum_perms AS fp ON (fp.forum_id=t.forum_id AND fp.group_id='.$pun_user['g_id'].') WHERE (fp.read_forum IS NULL OR fp.read_forum=1) AND p.poster_id IN('.implode(',', $user_ids).')'.$forum_sql.' ORDER BY '.$sort_by_sql.' '.$sort_dir) or error('Unable to fetch matched posts list', __FILE__, __LINE__, $db->error()); + while ($temp = $db->fetch_assoc($result)) + $author_results[$temp['post_id']] = $temp['topic_id']; + + $db->free_result($result); + } + } + + // If we searched for both keywords and author name we want the intersection between the results + if ($author && $keywords) + $search_ids = array_intersect_assoc($keyword_results, $author_results); + else if ($keywords) + $search_ids = $keyword_results; + else + $search_ids = $author_results; + + unset($keyword_results, $author_results); + + if ($show_as == 'topics') + $search_ids = array_values($search_ids); + else + $search_ids = array_keys($search_ids); + + $search_ids = array_unique($search_ids); + + $num_hits = count($search_ids); + if (!$num_hits) + message($lang_search['No hits']); + } + else if ($action == 'show_new' || $action == 'show_24h' || $action == 'show_user' || $action == 'show_subscriptions' || $action == 'show_unanswered') + { + // If it's a search for new posts + if ($action == 'show_new') + { + if ($pun_user['is_guest']) + message($lang_common['No permission']); + + $result = $db->query('SELECT t.id FROM '.$db->prefix.'topics AS t LEFT JOIN '.$db->prefix.'forum_perms AS fp ON (fp.forum_id=t.forum_id AND fp.group_id='.$pun_user['g_id'].') WHERE (fp.read_forum IS NULL OR fp.read_forum=1) AND t.last_post>'.$pun_user['last_visit'].' AND t.moved_to IS NULL'.(isset($_GET['fid']) ? ' AND t.forum_id='.intval($_GET['fid']) : '').' ORDER BY t.last_post DESC') or error('Unable to fetch topic list', __FILE__, __LINE__, $db->error()); + $num_hits = $db->num_rows($result); + + if (!$num_hits) + message($lang_search['No new posts']); + } + // If it's a search for todays posts + else if ($action == 'show_24h') + { + $result = $db->query('SELECT t.id FROM '.$db->prefix.'topics AS t LEFT JOIN '.$db->prefix.'forum_perms AS fp ON (fp.forum_id=t.forum_id AND fp.group_id='.$pun_user['g_id'].') WHERE (fp.read_forum IS NULL OR fp.read_forum=1) AND t.last_post>'.(time() - 86400).' AND t.moved_to IS NULL ORDER BY t.last_post DESC') or error('Unable to fetch topic list', __FILE__, __LINE__, $db->error()); + $num_hits = $db->num_rows($result); + + if (!$num_hits) + message($lang_search['No recent posts']); + } + // If it's a search for posts by a specific user ID + else if ($action == 'show_user') + { + $result = $db->query('SELECT t.id FROM '.$db->prefix.'topics AS t INNER JOIN '.$db->prefix.'posts AS p ON t.id=p.topic_id LEFT JOIN '.$db->prefix.'forum_perms AS fp ON (fp.forum_id=t.forum_id AND fp.group_id='.$pun_user['g_id'].') WHERE (fp.read_forum IS NULL OR fp.read_forum=1) AND p.poster_id='.$user_id.' GROUP BY t.id ORDER BY t.last_post DESC') or error('Unable to fetch topic list', __FILE__, __LINE__, $db->error()); + $num_hits = $db->num_rows($result); + + if (!$num_hits) + message($lang_search['No user posts']); + } + // If it's a search for subscribed topics + else if ($action == 'show_subscriptions') + { + if ($pun_user['is_guest']) + message($lang_common['Bad request']); + + $result = $db->query('SELECT t.id FROM '.$db->prefix.'topics AS t INNER JOIN '.$db->prefix.'subscriptions AS s ON (t.id=s.topic_id AND s.user_id='.$pun_user['id'].') LEFT JOIN '.$db->prefix.'forum_perms AS fp ON (fp.forum_id=t.forum_id AND fp.group_id='.$pun_user['g_id'].') WHERE (fp.read_forum IS NULL OR fp.read_forum=1) ORDER BY t.last_post DESC') or error('Unable to fetch topic list', __FILE__, __LINE__, $db->error()); + $num_hits = $db->num_rows($result); + + if (!$num_hits) + message($lang_search['No subscriptions']); + } + // If it's a search for unanswered posts + else + { + $result = $db->query('SELECT t.id FROM '.$db->prefix.'topics AS t LEFT JOIN '.$db->prefix.'forum_perms AS fp ON (fp.forum_id=t.forum_id AND fp.group_id='.$pun_user['g_id'].') WHERE (fp.read_forum IS NULL OR fp.read_forum=1) AND t.num_replies=0 AND t.moved_to IS NULL ORDER BY t.last_post DESC') or error('Unable to fetch topic list', __FILE__, __LINE__, $db->error()); + $num_hits = $db->num_rows($result); + + if (!$num_hits) + message($lang_search['No unanswered']); + } + + // We want to sort things after last post + $sort_by = 4; + $sort_dir = 'DESC'; + + $search_ids = array(); + while ($row = $db->fetch_row($result)) + $search_ids[] = $row[0]; + + $db->free_result($result); + + $show_as = 'topics'; + } + else + message($lang_common['Bad request']); + + + // Prune "old" search results + $old_searches = array(); + $result = $db->query('SELECT ident FROM '.$db->prefix.'online') or error('Unable to fetch online list', __FILE__, __LINE__, $db->error()); + + if ($db->num_rows($result)) + { + while ($row = $db->fetch_row($result)) + $old_searches[] = '\''.$db->escape($row[0]).'\''; + + $db->query('DELETE FROM '.$db->prefix.'search_cache WHERE ident NOT IN('.implode(',', $old_searches).')') or error('Unable to delete search results', __FILE__, __LINE__, $db->error()); + } + + // Fill an array with our results and search properties + $temp = serialize(array( + 'search_ids' => serialize($search_ids), + 'num_hits' => $num_hits, + 'sort_by' => $sort_by, + 'sort_dir' => $sort_dir, + 'show_as' => $show_as, + )); + $search_id = mt_rand(1, 2147483647); + + $ident = ($pun_user['is_guest']) ? get_remote_address() : $pun_user['username']; + + $db->query('INSERT INTO '.$db->prefix.'search_cache (id, ident, search_data) VALUES('.$search_id.', \''.$db->escape($ident).'\', \''.$db->escape($temp).'\')') or error('Unable to insert search results', __FILE__, __LINE__, $db->error()); + + if ($action != 'show_new' && $action != 'show_24h') + { + $db->end_transaction(); + $db->close(); + + // Redirect the user to the cached result page + header('Location: search.php?search_id='.$search_id); + exit; + } + } + + + // Fetch results to display + if (!empty($search_ids)) + { + switch ($sort_by) + { + case 1: + $sort_by_sql = ($show_as == 'topics') ? 't.poster' : 'p.poster'; + break; + + case 2: + $sort_by_sql = 't.subject'; + break; + + case 3: + $sort_by_sql = 't.forum_id'; + break; + + case 4: + $sort_by_sql = 't.last_post'; + break; + + default: + $sort_by_sql = ($show_as == 'topics') ? 't.last_post' : 'p.posted'; + break; + } + + // Determine the topic or post offset (based on $_GET['p']) + $per_page = ($show_as == 'posts') ? $pun_user['disp_posts'] : $pun_user['disp_topics']; + $num_pages = ceil($num_hits / $per_page); + + $p = (!isset($_GET['p']) || $_GET['p'] <= 1 || $_GET['p'] > $num_pages) ? 1 : intval($_GET['p']); + $start_from = $per_page * ($p - 1); + + // Generate paging links + $paging_links = ''.$lang_common['Pages'].' '.paginate($num_pages, $p, 'search.php?search_id='.$search_id); + + // throw away the first $start_from of $search_ids, only keep the top $per_page of $search_ids + $search_ids = array_slice($search_ids, $start_from, $per_page); + + $page_title = array(pun_htmlspecialchars($pun_config['o_board_title']), $lang_search['Search results']); + define('PUN_ACTIVE_PAGE', 'search'); + require PUN_ROOT.'header.php'; + + +?> +
    +
    + +
    +
    +
    + + +
    +

    +
    +
    + + + + + + + + + + +query('SELECT p.id AS pid, p.poster AS pposter, p.posted AS pposted, p.poster_id, p.message, p.hide_smilies, t.id AS tid, t.poster, t.subject, t.first_post_id, t.last_post, t.last_post_id, t.last_poster, t.num_replies, t.forum_id, f.forum_name FROM '.$db->prefix.'posts AS p INNER JOIN '.$db->prefix.'topics AS t ON t.id=p.topic_id INNER JOIN '.$db->prefix.'forums AS f ON f.id=t.forum_id WHERE p.id IN('.implode(',', $search_ids).') ORDER BY '.$sort_by_sql.' '.$sort_dir) or error('Unable to fetch search results', __FILE__, __LINE__, $db->error()); + else + $result = $db->query('SELECT t.id AS tid, t.poster, t.subject, t.last_post, t.last_post_id, t.last_poster, t.num_replies, t.closed, t.sticky, t.forum_id, f.forum_name FROM '.$db->prefix.'topics AS t INNER JOIN '.$db->prefix.'forums AS f ON f.id=t.forum_id WHERE t.id IN('.implode(',', $search_ids).') ORDER BY '.$sort_by_sql.' '.$sort_dir) or error('Unable to fetch search results', __FILE__, __LINE__, $db->error()); + + while ($cur_search = $db->fetch_assoc($result)) + { + $forum = ''.pun_htmlspecialchars($cur_search['forum_name']).''; + + if ($pun_config['o_censoring'] == '1') + $cur_search['subject'] = censor_words($cur_search['subject']); + + if ($show_as == 'posts') + { + ++$post_count; + $icon_type = 'icon'; + + if (!$pun_user['is_guest'] && $cur_search['last_post'] > $pun_user['last_visit'] && (!isset($tracked_topics['topics'][$cur_search['tid']]) || $tracked_topics['topics'][$cur_search['tid']] < $cur_search['last_post']) && (!isset($tracked_topics['forums'][$cur_search['forum_id']]) || $tracked_topics['forums'][$cur_search['forum_id']] < $cur_search['last_post'])) + { + $item_status = 'inew'; + $icon_type = 'icon icon-new'; + $icon_text = $lang_topic['New icon']; + } + else + { + $item_status = ''; + $icon_text = ''; + } + + if ($pun_config['o_censoring'] == '1') + $cur_search['message'] = censor_words($cur_search['message']); + + $message = parse_message($cur_search['message'], $cur_search['hide_smilies']); + $pposter = pun_htmlspecialchars($cur_search['pposter']); + + if ($cur_search['poster_id'] > 1) + { + if ($pun_user['g_view_users'] == '1') + $pposter = ''.$pposter.''; + else + $pposter = ''.$pposter.''; + } + + +?> +
    +

    # »  » 

    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    +
    +
    +
      +
    • +
    • +
    +
    +
    +
    +
    +
    +'.pun_htmlspecialchars($cur_search['subject']).''.$lang_common['by'].' '.pun_htmlspecialchars($cur_search['poster']).''; + + if ($cur_search['sticky'] == '1') + { + $item_status .= ' isticky'; + $status_text[] = ''.$lang_forum['Sticky'].''; + } + + if ($cur_search['closed'] != '0') + { + $status_text[] = ''.$lang_forum['Closed'].''; + $item_status .= ' iclosed'; + } + + if (!$pun_user['is_guest'] && $cur_search['last_post'] > $pun_user['last_visit'] && (!isset($tracked_topics['topics'][$cur_search['tid']]) || $tracked_topics['topics'][$cur_search['tid']] < $cur_search['last_post']) && (!isset($tracked_topics['forums'][$cur_search['forum_id']]) || $tracked_topics['forums'][$cur_search['forum_id']] < $cur_search['last_post'])) + { + $item_status .= ' inew'; + $icon_type = 'icon icon-new'; + $subject = ''.$subject.''; + $subject_new_posts = '[ '.$lang_common['New posts'].' ]'; + } + else + $subject_new_posts = null; + + // Insert the status text before the subject + $subject = implode(' ', $status_text).' '.$subject; + + $num_pages_topic = ceil(($cur_search['num_replies'] + 1) / $pun_user['disp_posts']); + + if ($num_pages_topic > 1) + $subject_multipage = '[ '.paginate($num_pages_topic, -1, 'viewtopic.php?id='.$cur_search['tid']).' ]'; + else + $subject_multipage = null; + + // Should we show the "New posts" and/or the multipage links? + if (!empty($subject_new_posts) || !empty($subject_multipage)) + { + $subject .= !empty($subject_new_posts) ? ' '.$subject_new_posts : ''; + $subject .= !empty($subject_multipage) ? ' '.$subject_multipage : ''; + } + +?> + + + + + + +'."\n\t\t\t".'
    +
    +
    +
    + +
    +
    +
    '.format_time($cur_search['last_post']).' '.$lang_common['by'].' '.pun_htmlspecialchars($cur_search['last_poster']) ?>
    '."\n\t\t".'
    '."\n\t".'
    '."\n".'
    '."\n\n"; + +?> +
    +
    + +
    +
    +
    + +
    +

    +
    + +
    +
    +.. diff --git a/style/Air/img/main_end.png b/style/Air/img/main_end.png new file mode 100644 index 0000000..14fb076 Binary files /dev/null and b/style/Air/img/main_end.png differ diff --git a/style/Air/img/main_top.png b/style/Air/img/main_top.png new file mode 100644 index 0000000..b98d1bb Binary files /dev/null and b/style/Air/img/main_top.png differ diff --git a/style/Air/index.html b/style/Air/index.html new file mode 100644 index 0000000..89337b2 --- /dev/null +++ b/style/Air/index.html @@ -0,0 +1 @@ +.. diff --git a/style/Cobalt.css b/style/Cobalt.css new file mode 100644 index 0000000..a4c49a7 --- /dev/null +++ b/style/Cobalt.css @@ -0,0 +1,1086 @@ +/***************************************************************** +1. INITIAL SETTINGS +*****************************************************************/ + +/* Limited Reset +----------------------------------------------------------------*/ + +.pun table, .pun div, .pun form, .pun p, .pun h1, .pun h2, .pun h3, +.pun h4, .pun h5, .pun pre, .pun blockquote, .pun ul, .pun ol, .pun li, .pun dl, +.pun dt, .pun dd, .pun th, .pun td, .pun fieldset, .pun img, .pun abbr, .pun cite { + margin: 0; + padding: 0; + border: 0; + } + +.pun ul, .pun ol { + list-style: none + } + + +/* Structural Settings +----------------------------------------------------------------*/ + +.pun .clearer, .pun .nosize { + height: 0; + width: 0; + line-height: 0; + font-size: 0; + overflow: hidden + } + +.pun .clearer, .pun .clearb { + clear: both + } + +.pun .nosize { + position: absolute; + left: -9999em; + text-indent: -9999em; + width: 0; + } + +* html .inbox, * html .inform, * html .pun, * html .tclcon, * html .codebox { + height: 1px + } + +.pun, .pun .inbox, .pun .inform, .pun .tclcon, .pun .codebox { + min-height: 1px + } + + +/* Hidden Elements +----------------------------------------------------------------*/ + +#brdfooter h2, #brdstats h2, #brdstats .conl dt, #brdstats .conr dt, +#modcontrols dt, #searchlinks dt, div.postright h3, span.closedtext, +.pun .required strong span { + position: absolute; + display: block; + overflow: hidden; + width: 0; + left: -9999em; + text-indent: -9999em; + } + +/***************************************************************** +2. TEXT & CONTENT +*****************************************************************/ + +/* Text Defaults +----------------------------------------------------------------*/ + +.pun { + font: 68.75%/1.4545em Verdana, Helvetica, Arial, sans-serif; + } + +.pun table, .pun td, .pun th, .pun input, .pun select, .pun optgroup, .pun textarea, .pun samp { + font-size: 1em; + font-family: verdana, helvetica, arial, sans-serif; + } + +.pun pre, .pun code { + font-size: 1.182em; + font-family: consolas, monaco, "bitstream vera sans mono", "courier new", courier, monospace + } + +.pun pre code { + font-size: 1em; + } + +.pun strong { + font-weight: bold; + } + +.pun em { + font-style: italic; + } + + +/* Content Defaults +----------------------------------------------------------------*/ + +.pun p, .pun ul, .pun ol, .pun dl { + font-size: 1em; + padding: 3px 0; + } + +.pun h2 { + font-size: 1em; + font-weight: normal; + padding: 4px 7px; + } + +.pun h3 { + font-size: 1.091em; + padding: 3px 0; + } + +.pun table p, .pun table h3 { + padding: 0; + } + +.pun span.warntext, .pun p.warntext { + font-weight: bold + } + +/* User Content (Announcements, Rules, Posts) +----------------------------------------------------------------*/ + +.pun .usercontent p, .pun .postmsg p { + padding: 0.75em 0 + } + +.pun .usercontent ul, .pun .postmsg ul { + padding: 0.75em 1em 0.75em 2.5em; + list-style: disc + } + +.pun .usercontent ol, .pun .postmsg ol { + padding: 0.75em 1em 0.75em 2.5em; + list-style: decimal + } + +.pun .usercontent ol.alpha, .pun .postmsg ol.alpha { + list-style: lower-alpha + } + +.pun .usercontent li ol, .pun .usercontent li ul, .pun .postmsg li ol, .pun .postmsg li ul { + padding: 0.25em 1em 0.75em 2.5em + } + +.pun .usercontent li p, .pun .postmsg li p { + padding: 0 + } + +.pun .usercontent h1 { + font-size: 1.4em; + font-weight: bold; + padding: 0.75em 0 0 0 + } + +.pun .usercontent h2 { + font-size: 1.2em; + font-weight: bold; + padding: 0.75em 0 0 0 + } + +.pun .usercontent h3 { + font-size: 1.1em; + font-weight: bold; + padding: 0.75em 0 0 0 + } + +.pun .usercontent h4, .pun .usercontent h5, .pun .usercontent h6 { + font-size: 1em; + font-weight: bold; + padding: 0.75em 0 0 0 + } + +.pun .quotebox cite { + font-weight: bold; + font-style: normal; + padding: 0.75em 0.75em 0 0.75em + } + +.pun span.bbu { + text-decoration: underline + } + +.pun span.bbs, .pun del { + text-decoration: line-through; + } + +.pun .postmsg ins, #punhelp samp ins { + text-decoration: none; + } + +.pun div.postmsg h5, #punhelp h5 { + font-size: 1.1em; + font-weight: bold; + padding: 0.75em 0 0 0; + } + + +/***************************************************************** +3. COMMON STYLES +*****************************************************************/ + +/* Page Layout +----------------------------------------------------------------*/ + +.pun { + margin: 12px 20px + } + +#punredirect, #punmaint, #puninstall, #pundb_update { + margin: 50px 20% 12px 20% + } + + +/* Vertical Element Spacing +----------------------------------------------------------------*/ + +#brdheader { + margin: 0 0 12px 0; + } + +#announce, #brdstats { + margin: 12px 0 12px 0; + } + +.pun .blocktable, .pun .block, .pun .blockform, .pun .block2col, #postreview { + margin-bottom: 12px + } + +#punindex .blocktable, .pun .blockpost { + margin-bottom: 6px + } + +#postreview .blockpost { + margin-bottom: -1px; + } + +.pun .block2col .blockform, .pun .block2col .block { + margin-bottom: 0px + } + +.pun .linkst, .pun .linksb { + margin-top: -12px + } + +.pun .postlinksb { + margin-top: -6px + } + + +/* External Borders +----------------------------------------------------------------*/ + +.pun .box { + border-style: solid; + border-width: 1px; + } + +#brdheader .box { + border-top-width: 4px; + } + +/* Default Internal Spacing +----------------------------------------------------------------*/ + +.pun .block .inbox, .pun .blockmenu .inbox { + padding: 3px 6px + } + +/***************************************************************** +4. COMMON BOARD ELEMENTS +*****************************************************************/ + +/* Board Header +----------------------------------------------------------------*/ + +#brdtitle h1 { + font-size: 1.454em; + font-weight: bold; + line-height: 1em; + padding: 3px 0 0 0; + } + +#brddesc { + padding: 3px 0; + } + +#brddesc * { + padding-top: 0; + padding-bottom: 0; + } + +#brdmenu li { + display: inline; + margin-right: 12px; + } + +#brdmenu a:link, #brdmenu a:visited { + text-decoration: none + } + +#brdmenu a:hover, #brdmenu a:active { + text-decoration: underline + } + +#brdwelcome .conl { + float: left; + } + +#brdwelcome .conr { + float: right; + text-align: right; + } + +/* Breadcrumbs and Post Links +----------------------------------------------------------------*/ + +.pun .linkst { + padding: 8px 6px 3px 6px + } + +.pun .linksb, .pun .postlinksb { + padding: 3px 6px 8px 6px + } + +.pun .crumbs { + clear: both; + width: 100%; + overflow: hidden; + } + +.pun .crumbs li { + display: inline; + white-space: nowrap; + font-weight: bold; + } + +.pun .pagelink { + float: left; + white-space: nowrap; + } + +.pun .postlink { + font-weight: bold; + white-space: nowrap; + } + +.pun .postlink, .pun .modbuttons { + float: right; + text-align: right; + } + +.pun .modbuttons { + padding: 1px 0; + white-space: nowrap; + } + +.pun .modbuttons input { + margin-left: 6px; + } + +.pun .postlink a:link, .pun .postlink a:visited { + text-decoration: none + } + +.pun .postlink a:hover, .pun .postlink a:active { + text-decoration: underline; + } + + +/* Board Footer +----------------------------------------------------------------*/ + +#brdfooter .conl { + float: left; + } + +#brdfooter .conr { + float: right; + text-align: right; + } + +#brdfooter #modcontrols { + border-bottom-style: solid; + border-bottom-width: 1px; + text-align: center; + } + +#brdfooter #modcontrols dd { + display: inline; + margin:0 6px; + } + + +/* Board Stats +----------------------------------------------------------------*/ + +#brdstats .conl { + float: left; + } + +#brdstats .conr { + float: right; + text-align: right; + } + +#onlinelist dd, #onlinelist dt { + display: inline; + } + + +/***************************************************************** +5. MAIN TABLES +*****************************************************************/ + +.pun table { + width: 100%; + border-collapse: collapse; + border-spacing: 0; + empty-cells: show; + } + +.pun .blocktable table { + table-layout: fixed; + } + +.pun td, .pun th { + padding: 4px 6px; + line-height: 1.273em; + text-align: left; + font-weight: normal; + } + +.pun td { + border-style: solid none none solid; + border-width: 1px; + } + +.pun .tcl { + border-left: 0; + width: auto; + } + +.pun .tc2, .pun .tc3, .pun .tcmod { + width: 10%; + text-align: center; + padding: 4px 0; + } + +.pun .tcr { + width: 30%; + } + +.pun .tcl h3 { + font-size: 1.091em; + font-weight: bold; + } + +.pun .tcl h3 span.newtext { + font-size: 0.917em; + } + +.pun .tcl span.newtext, .pun .tcl span.pagestext { + white-space: nowrap; + font-weight: normal; + } + +.pun td span.byuser { + white-space: nowrap; + } + +.pun .tcl p { + padding: 5px 0 0 0 + } + +#punsearch #vf .tc2 { + width: 18%; + text-align: left; + padding: 4px 6px; + } + +#users1 .tcr { + width: 25% + } + +#users1 .tc2 { + width: 25%; + text-align: left; + padding: 4px 6px; + } + +#debug .tcl { + width: 10% + } + +#debug .tcr { + width: 90%; + white-space: normal + } + +#punindex .tcr .byuser { + display: block + } + +.pun .blocktable .tclcon { + padding: 0 11px 0 12px; + overflow: hidden; + height: 1%; + min-height: 1px; + position: relative; + } + +.pun .blocktable .tclcon div { + width: 100%; + overflow: hidden; + } + +.pun .icon { + border-width: 7px; + border-style: solid; + height: 0; + width: 0; + overflow: hidden; + float: left; + } + +.pun .icon div { + position: absolute; + left: -9999em; + text-indent: -9999em; + height: 0; + } + +.pun .iposted .ipost { + position: absolute; + left: 0; + font-weight: bold; + width: 8px; + padding-left: 4px; + text-align: center; + top: 0; + } + +/***************************************************************** +6. MAIN FORMS +*****************************************************************/ + +.pun .blockform form, .pun .fakeform { + PADDING: 20px 20px 15px 20px + } + +.pun .forminfo { + margin-bottom: 12px; + padding: 9px 10px; + border-style: solid; + border-width: 1px; + } + +.pun .forminfo h3 { + font-weight: bold; + } + +.pun .inform { + padding-bottom: 12px + } + +.pun fieldset { + padding: 0px 12px 0px 12px; + border-style: solid; + border-width: 1px + } + +.pun legend { + padding: 0px 6px + } + +.pun .infldset { + padding: 9px 0px 12px 0 + } + +.pun label { + display: block; + padding: 3px 0 + } + +.pun label.conl { + float: left; + overflow: visible; + margin-right: 10px + } + +.pun select { + padding-top: 1px; + padding-bottom: 1px; + } + +.pun fieldset .rbox { + } + +.pun fieldset .rbox br { + display: none; + } + +.pun fieldset .rbox label { + padding: 3px 0 3px 25px; + position: relative; + vertical-align: middle; + } + +.pun fieldset .rbox input { + margin: 0 9px 0 -25px; + padding: 0; + width: 16px; + position: relative; + vertical-align: middle; + } + +.pun .txtarea { + width: 75% + } + +.pun .txtarea textarea, .pun input.longinput { + width: 100% + } + +.pun .bblinks { + padding-bottom: 10px; + padding-left: 4px + } + +.pun .bblinks li { + display: inline; + padding-right: 20px + } + +.pun .blockform .buttons { + padding-left: 12px; + } + +.pun .blockform .buttons input { + margin-right: 8px; + } + +#posterror ul { + list-style: square; + padding: 3px 0 3px 24px; + } + +.pun .deletemsg { + border-style: solid; + border-width: 1px; + padding: 6px 15px; + } + +.pun p.actions span { + margin-right: 12px; + } + +/***************************************************************** +7. PROFILES AND ADMIN +*****************************************************************/ + +.pun .block2col { + padding-bottom: 1px + } + +.pun .block2col .blockform, .pun .block2col .block { + margin-left: 17em + } + +.pun .blockmenu { + float:left; + width: 16em + } + +.pun .blockmenu li { + padding: 3px 0; + font-weight: bold; + } + +.pun .blockmenu a:link, .pun .blockmenu a:visited { + text-decoration: none + } + +.pun .blockmenu a:hover, .pun .blockmenu a:active { + text-decoration: underline + } + +#viewprofile dl { + float: left; + width: 100%; + overflow: hidden + } + +#viewprofile dd { + margin-left: 14em; + padding: 3px; + } + +#viewprofile dt { + float: left; + width: 13em; + margin: 3px 0; + } + +#profileavatar img { + float: right; + margin-left: 1em + } + +/***************************************************************** +8. MAIN POSTS +*****************************************************************/ + +.pun .blockpost h2 a:link, .pun .blockpost h2 a:visited { + text-decoration: none; + } + +.pun .blockpost h2 a:hover, .pun .blockpost h2 a:active { + text-decoration: underline; + } + +.pun .blockpost h2 .conr { + float: right; + text-align: right; + } + +#punsearch .blockpost h2 span { + white-space: nowrap; + } + +.pun .blockpost .box { + overflow: hidden; + } + +.pun .postleft, .pun .postfootleft { + float:left; + width: 18em; + position: relative; + overflow: hidden; + } + +.pun .postleft dl { + padding: 0.75em 6px; + } + +.pun .postleft .usercontacts, .pun .postleft .icon { + margin-top: 6px + } + +.pun .postleft .postavatar, .pun .postleft .usertitle { + margin-bottom: 6px; + display: block; + } + +.pun .blockpost dt { + font-size: 1.091em; + font-weight: bold; + } + +.pun .blockpost dt a:link, .pun .blockpost dt a:visited { + text-decoration: none; + } + +.pun .blockpost dt a:hover, .pun .blockpost dt a:active { + text-decoration: underline; + } + +.pun .postright, .pun .postfootright { + border-left-width: 18em; + border-left-style: solid + } + +#postpreview .postright { + border-left: 0 + } + +.pun .postright { + padding: 0 6px; + } + +.pun .postfootright, .pun .multidelete { + text-align: right + } + +.pun .postmsg { + width:98%; + overflow: hidden; + padding-bottom: 6px; + } + +.pun .postfootright ul, .pun .postfootright div, .pun .postfootright p, +.pun .postfootleft p { + padding: 6px 6px 6px 6px; + } + +.pun .postfootright li { + display: inline; + margin-left: 12px; + } + +.pun .postfootright a:link, .pun .postfootright a:visited { + text-decoration: none + } + +.pun .postfootright a:hover, .pun .postfootright a:active { + text-decoration: underline + } + +.pun .codebox { + border-style: solid; + border-width: 1px; + margin: 0.75em 1em; + padding: 0; + } + +.pun .quotebox { + border-style: solid; + border-width: 1px; + margin: 0.75em 1em; + padding: 0 0.75em; + } + +.pun .quotebox cite { + display: block; + padding: 0.75em 0 0 0; + } + +.pun .quotebox blockquote { + width: 100%; + overflow: hidden + } + +.pun .codebox pre { + overflow: auto; + width: 100%; + overflow-y:hidden + } + +* html .pun .codebox pre { + padding-bottom: 10px; + } + +*+html .pun .codebox pre { + padding-bottom: 10px + } + +.pun .codebox pre code { + display: block; + padding: 0.75em; + } + +.pun .codebox pre.vscroll { + height: 32em; + overflow: auto; + overflow-y: auto + } + +.pun .postmsg img { + vertical-align: bottom; + } + +.pun .postsignature hr { + margin-left: 0px; + width: 200px; + text-align: left; + height: 1px; + border:none + } + +.pun .postmsg .postimg img { + max-width: 98%; + vertical-align: middle; +} + +.pun .postmsg .postimg a:link img, .pun .postmsg .postimg a:visited img { + border-style: solid; + border-width: 2px; +} + +.pun .blockpost label { + padding: 3px 6px; + border-style: solid; + border-width: 1px; + vertical-align: middle; + display: inline-block; + } + +.pun .blockpost label * { + vertical-align: middle; + margin: 0; + padding: 0; + } + +/****************************************************************/ +/* 9. HELP FILES AND MISC. */ +/****************************************************************/ + +#punhelp h2 { + margin-top: 12px + } + +#punhelp div.box { + padding: 10px + } + +#debugtime { + margin-top: -12px; + text-align: center; + } + +/***************************************************************** +COLOUR SCHEME +*****************************************************************/ + +/* Background / Text +----------------------------------------------------------------*/ + +body { + background: #2a2a2a; + color: #d4d4d4 + } + +.pun { + color: #d4d4d4 + } + +.pun .box, #adminconsole fieldset th { + background-color: #383838 + } + +.pun td.tc2, .pun td.tc3, .pun td.tcmod, #postpreview, #viewprofile dd, .pun .forminfo, +#brdfooter #modcontrols, #adminconsole fieldset td, .pun .blockmenu .box, #adstats dd { + background-color: #424242 + } + +.pun h2, #brdmenu { + background-color: #565656; + color: #d4d4d4 + } + +.pun th { + background-color: #484848 + } + +.pun legend { + color: #60a0dc + } + +.pun .blockmenu li.isactive a, #posterror li strong { + color: #d4d4d4 + } + +.pun .usercontent * { + background: transparent; + color: #d4d4d4 + } + +.pun textarea, .pun input, .pun select { + background-color: #2a2a2a; + color: #d4d4d4 + } + +/* Posts +----------------------------------------------------------------*/ + +.pun .blockpost .box, .pun .postright, .pun .postfootright, .pun .deletemsg { + background-color: #383838 + } + +.pun .postright, .pun .postfootright { + border-left-color: #424242 + } + +.pun .postleft, .pun .postfootleft, .pun .blockpost label, .pun .codebox, .pun .quotebox { + background-color: #424242 + } + +.pun .blockpost h2 { + background-color: #565656 + } + +.pun .blockpost h2 span.conr { + color: #a19e96 + } + +.pun .postmsg ins, #punhelp samp ins { + background-color: #ff0; + } + +.pun hr { + background-color: #606060; + color: #606060 + } + +/* Borders +----------------------------------------------------------------*/ + +.pun .box { + border-color:#565656 + } + +.pun td, #brdfooter #modcontrols { + border-color: #565656 + } + +.pun th, .pun fieldset { + border-color: #484848 + } + +#adminconsole td, #adminconsole th { + border-color: #383838 + } + +.pun .quotebox, .pun .codebox, .pun .forminfo, +.pun .blockpost label, .pun .deletemsg { + border-color: #606060 + } + +/* Links +----------------------------------------------------------------*/ + +.pun a:link, .pun a:visited { + color: #60a0dc + } + +.pun a:hover, .pun a:active, .pun a:focus { + color: #80d6ff + } + +.pun .postmsg .postimg a:link img, .pun .postmsg .postimg a:visited img { + border-color: #60a0dc; +} + +.pun .postmsg .postimg a:hover img, .pun .postmsg .postimg a:active img, .pun .postmsg .postimg a:focus img { + border-color: #80d6ff; +} + +.pun h2 a:link, .pun h2 a:visited, +#brdmenu a:link, #brdmenu a:visited { + color: #d4d4d4 + } + +.pun h2 a:hover, .pun h2 a:active, +#brdmenu a:hover, #brdmenu a:active { + color: #d4d4d4 + } + +.pun .postreport a:link, .pun .postreport a:visited, +.pun .iclosed td.tcl a:link, .pun .iclosed td.tcl a:visited { + color: #888 + } + +.pun .postreport a:hover, .pun .postreport a:active, +.pun .iclosed td.tcl a:hover, .pun .iclosed td.tcl a:active { + color: #aaa + } + +.pun .maintenancelink a:link, .pun .maintenancelink a:visited { + color: #ff4000 + } + +.pun .maintenancelink a:hover, .pun .maintenancelink a:active { + color: #ff5010 + } + +/* Status Indicators +----------------------------------------------------------------*/ + +.pun .icon { + border-color: #484848 #404040 #3c3c3c #444444 + } + +.pun .iredirect .icon { + border-color: #383838 #383838 #383838 #383838 + } + +.pun .inew .icon { + border-color: #5496d8 #4b85c0 #4377ac #4f8dcb + } diff --git a/style/Earth.css b/style/Earth.css new file mode 100644 index 0000000..225b4a4 --- /dev/null +++ b/style/Earth.css @@ -0,0 +1,1601 @@ +/***************************************************************** +1. INITIAL SETTINGS +*****************************************************************/ + +/* Limited Reset +----------------------------------------------------------------*/ + +html, body, .pun table, .pun div, .pun form, .pun p, .pun h1, .pun h2, .pun h3, .pun h4, .pun h5, .pun pre, .pun blockquote, +.pun ul, .pun ol, .pun li, .pun dl, .pun dt, .pun dd, .pun th, .pun td, .pun fieldset, .pun legend .pun img, +.pun abbr, .pun cite { + border: 0; + font-style: normal; + font-weight: normal; + margin: 0; + padding: 0; +} + +.pun ul, .pun ol { + list-style: none; +} + +.pun select { + padding-bottom: 1px; + padding-top: 1px; +} + +/* Content Defaults +----------------------------------------------------------------*/ + +.pun { + font: 81.25%/1.462em Arial, Helvetica, sans-serif; +} + +.pun table, .pun td, .pun th, .pun input, .pun select, .pun optgroup, .pun textarea { + font-family: Arial, Helvetica, sans-serif; + font-size: 1em; +} + +.pun pre, .pun code { + font-family: consolas, monaco, "bitstream vera sans mono", "courier new", courier, monospace; + font-size: 1em; +} + +.pun pre code { + font-size: 1em; +} + +.pun table { + border-collapse: collapse; + border-spacing: 0; + border: 0; + empty-cells: show; + width: 100%; +} + +.pun h1 { + font:2.154em/1em "Trebuchet MS", Arial, Helvetica, sans-serif; + padding: 7px 0; +} + +.pun h2, .pun .hd h2 { + font: 1.462em/1em "Trebuchet MS", Arial, Helvetica, sans-serif; + padding: 7px 0; +} + +.pun h3 { + font-size: 1.154em; + line-height: 1.267em; + padding: 7px 0; +} + +.pun h4 { + font-size: 1.077em; + font-weight: bold; + padding: 7px 0; +} + +.pun h5, .pun h6 { + font-size: 1em; + font-weight: bold; + padding: 7px 0; +} + +.pun p, .pun ul, .pun ol, .pun dl, .pun th, .pun td, .pun legend { + padding: 7px 0; +} + +.pun strong, .pun th, .pun span.warntext, .pun p.warntext { + font-weight: bold; +} + +.pun em { + font-style: italic; +} + +.pun a, .pun a:link, .pun a:visited { + text-decoration: none; +} + +.pun a:hover, .pun a:active, .pun a:focus { + text-decoration: underline; +} + +.pun .actions span { + padding-left: 16px; + padding-right: 8px; + background: url(Earth/img/bull.png) center left no-repeat; + display: inline-block; + line-height: normal; +} + +/* Hidden Elements +----------------------------------------------------------------*/ + +#brdfooter h2, #brdstats h2, #debug h2, #brdstats .conl dt, #brdstats .conr dt, #modcontrols dt, +#searchlinks dt, div.postright h3, .pun .subscribelink span, #announce .hd, #reportform h2, #punmoderate #vf h2, +#punviewforum #vf h2, .pun .required strong span, .pun .icon div { + display: block; + overflow: hidden; + position: absolute; + text-indent: -9999em; + width: 0; +} + +/* Generic Float Clear +----------------------------------------------------------------*/ + +.pun .inbox, .pun #brdmain, .pun .crumbs, .pun .pagepost, .pun .block2col { + min-height: 1px; +} + +* html .pun .inbox, * html .pun #brdmain, * html .pun .infldset, * html .pun .crumbs, * html .pun .pagepost, * html .pun .block2col { + display: inline-block; +} + +* html .pun .inbox, * html .pun #bdrdmain, * html .pun .infldset, * html .pun .crumbs, * html .pun .pagepost, * html .pun .block2col { + display: block; +} + +.pun .inbox:after, .pun #brdmain:after, .pun .crumbs:after, .pun .pagepost:after, .pun .block2col:after { + content: " "; + display: block; + height: 0; + font-size: 0; + clear: both; + visibility: hidden; +} + +.pun .block2col .inbox:after { + content: none; + clear: none; +} + +/***************************************************************** +2. COMMON STYLES +*****************************************************************/ + +/* Page Layout +----------------------------------------------------------------*/ + +.pun { + padding: 30px 40px; +} + +#punredirect, #punmaint { + padding: 60px 20% 12px 20%; +} + +#puninstall, #pundb_update { + padding: 20px 10%; +} + +.pun .punwrap { + border: 1px solid; + padding: 18px; +} + +.pun .top-box { + height: 18px; + margin-bottom: -18px; + position: relative; + background: url(Earth/img/main_top.png) top left no-repeat; +} + +.pun .top-box div { + height: 18px; + margin-left: 50%; + background: url(Earth/img/main_top.png) top right no-repeat; +} + +.pun .end-box { + margin-top: -17px; + height: 18px; + position: relative; + background: url(Earth/img/main_end.png) bottom left no-repeat; +} + +.pun .end-box div { + height: 18px; + margin-left: 50%; + background: url(Earth/img/main_end.png) bottom right no-repeat; +} + +#punredirect h2, #punmaint h2 { + border-bottom-style: dotted; + border-bottom-width: 1px; + margin-bottom: 3px; +} + +/* Section Spacing and Borders +----------------------------------------------------------------*/ + +#brdmain { + border-style: solid none; + border-width: 2px 0; + margin-bottom: 12px; + padding: 12px 0; +} + +#punindex #brdmain { + padding-top: 24px; +} + +#punredirect #brdmain, #punmaint #brdmain { + border: 0; + margin: 0; + padding: 0; +} + +#brdstats { + border-style: solid none none none; + border-width: 2px 0 0 0; + margin-top: 24px; + padding-top: 12px; +} + +#quickpost { + border-style: solid none none none; + border-width: 2px 0 0 0; + margin-top: 12px; + padding-top: 12px; +} + +#announce { + border-style: solid none none none; + border-width: 2px 0 0 0; + padding-top: 3px; +} + +/***************************************************************** +3. COMMON BOARD ELEMENTS +*****************************************************************/ + +/* Logo, Description and Main Menu +----------------------------------------------------------------*/ + +#brdtitle h1 { + padding: 0 0 10px 0; +} + +#brddesc { + border-top-style: dotted; + border-top-width: 1px; + padding: 10px 0; +} + +#brddesc p { + padding: 0; +} + +#brdmenu ul { + padding: 0; +} + +#brdmenu li { + float: left; +} + +#brdmenu a:link, #brdmenu a:visited { + border-right-style: solid; + border-width: 1px; + display: inline-block; + min-width: 60px; + padding: 12px 16px 6px 8px; + white-space: nowrap; +} + +#brdmenu a:hover, #brmenu a:active, #brdmenu a:focus { + text-decoration: none; +} + +/* Welcome Box +----------------------------------------------------------------*/ + +#brdwelcome { + padding: 10px 0; +} + +#brdwelcome .conl, #brdwelcome .conr, #brdwelcome p, #brdwelcome li { + display: inline; + padding: 0; +} + +#brdwelcome li span { + background: url(Earth/img/bull.png) center left no-repeat; + padding-left: 18px; + margin-right: 3px; + display: inline-block; + line-height: normal; + white-space: nowrap; +} + +#brdwelcome .conl li:first-child span { + padding-left: 0; + background: none; +} + +/* Stats +----------------------------------------------------------------*/ + +#brdstats .conl { + float: left; +} + +#brdstats .conr { + float: right; + text-align: right; +} + +#brdstats #onlinelist { + border-top-style: dotted; + border-top-width: 1px; + clear: both; +} + +#brdstats #onlinelist dt, #brdstats #onlinelist dd { + display: inline; +} + +/* Footer +----------------------------------------------------------------*/ + +.pun #modcontrols { + border-style: none none dotted none; + border-width: 0 0 1px 0; + margin-bottom: 4px; + text-align: center; + width: 100%; +} + +.pun #modcontrols dd { + display: inline; +} + +.pun #brdfooter #modcontrols dd span { + background: url(Earth/img/bull.png) center left no-repeat; + display: inline-block; + line-height: normal; + padding-left: 18px; + white-space: nowrap; +} + +.pun #brdfooter .conl { + float: left; +} + +.pun #brdfooter .conr { + text-align: right; + float: right; +} + +.pun #brdfooter #poweredby a { + font-size: 1.077em; + font-weight: bold; +} + +.pun #brdfooter #qjump { + padding-top: 5px; +} + +.pun #brdfooter #qjump * { + white-space: nowrap; +} + +.pun #brdfooter #searchlinks dd span { + background: url(Earth/img/bull.png) center left no-repeat; + display: inline-block; + line-height: normal; + padding-left: 18px; + white-space: nowrap; +} + +.pun #brdfooter #feedlinks { + padding-bottom: 0; +} + +.pun #brdfooter #feedlinks span { + background: url(Earth/img/feed.png) center left no-repeat; + display: inline-block; + padding-left: 18px; + white-space: nowrap; +} + +.pun #debugtime { + border-style: dotted none none none; + border-width: 1px 0 0 0; + margin-top: 7px; + text-align: center; +} + +/* Breadcrumbs, Postlink, Pagination +----------------------------------------------------------------*/ + +.pun .linkst .inbox, .pun linksb .inbox, .pun .postlinksb .inbox { + overflow: hidden; +} + +.pun .linksb, .pun .postlinksb, .pun .linkst, .pun .crumbs { + clear: both; + position: relative; +} + +.pun .linkst .crumbs { + font-family: "Trebuchet MS", Helvetica, Arial, sans-serif; + font-size: 1.462em; + line-height: 1.211em; + padding: 7px 0; +} + +.pun .linksb .crumbs, .pun .postlinksb .crumbs { + font-family: "Trebuchet MS", Helvetica, Arial, sans-serif; + font-size: 1.154em; +} + +.pun .linkst .crumbsplus .pagepost { + border-top-style: dotted; + border-top-width: 1px; +} + +.pun .linksb .crumbsplus .pagepost, .pun .postlinksb .crumbsplus .pagepost { + border-bottom-style: dotted; + border-bottom-width: 1px; +} + +.pun .postlinksb .crumbs { + margin-right: 11em; +} + +.pun .crumbs li { + float: left; + padding-right: 0.4em; + white-space: nowrap; +} + +.pun .crumbs li strong { + font-weight: normal; +} + +.pun .pagelink { + float: left; + white-space: nowrap; +} + +.pun .pagelink strong, .pun .pagelink a, .pun .pagelink span.spacer { + border-style: none none none solid; + border-width: 0 0 0 1px; + display: inline-block; + padding: 0 12px 0 10px; + margin-right: -6px; +} + +.pun .pagelink .item1 { + border: 0; +} + +.pun .pagelink .pages-label { + display: inline-block; +} + +.pun .postlink { + float: right; + font-weight: bold; + text-align: right; +} + +.pun .modbuttons { + float: right; + padding: 5px 0 3px 0; +} + +.pun .modbuttons input { + margin-left: 8px; +} + +.pun .subscribelink { + position: absolute; + right: 0; + text-align: right; + top: 33px; +} + +/***************************************************************** +4. MAIN TABLES +*****************************************************************/ + +#punindex #brdmain .blocktable h2, #punsearch #vf h2 { + font: 1em/1.462em Arial, Helvetica, sans-serif; + font-weight: bold; + margin: 1px 1px 0 1px; + padding-left: 8px; + position: absolute; + white-space: nowrap; + z-index: 100; +} + +#punindex .blocktable th.tcl, #punsearch #vf th.tcl { + font-size: 0; + text-indent: -9999em; +} + +.pun .blocktable .box { + border-style: solid; + border-width: 1px; + margin-bottom: -1px; + overflow: hidden; + position: relative; +} + +* html .pun .blocktable .box { + display: inline-block; +} + +.pun .blocktable table { + table-layout: fixed; + margin-bottom: -1px; +} + +.pun .blocktable th { + padding: 7px 8px; + border-style: none none solid none; + border-width: 1px; + text-align: left; +} + +.pun .blocktable td { + padding: 7px 8px; + line-height: 1.3077em; + border-style: none none solid none; + border-width: 1px; + text-align: left; +} + +.pun .blocktable h3 { + font-size: 1.077em; + font-weight: bold; + padding: 0; +} + +.pun .blocktable p { + padding: 0; +} + +.pun .blocktable .tcl p { + padding: 5px 0 0 0; +} + +.pun .blocktable .tcl { + width: auto; +} + +.pun .blocktable .tc2, .pun .blocktable .tc3, .pun .blocktable .tcmod { + padding-left: 0; + padding-right: 0; + text-align: center; + width: 11%; +} + +.pun .blocktable .tcr { + width: 30%; +} + +.pun .blocktable td .newtext, .pun .blocktable td .pagestext, .pun .blocktable td .byuser { + white-space: nowrap; +} + +.pun .blocktable .tcl h3 span.newtext { + font-size: 0.929em; + font-weight: normal; +} + +.pun #vf td.tcl span.stickytext, .pun #vf td.tcl span.closedtext { + font-size: 1em; + font-weight: bold; +} + +#punsearch #vf .tc2 { + padding-left: 8px; + padding-right: 8px; + text-align: left; + width: 18%; +} + +#users1 .tcr { + width: 25%; +} + +#users1 .tc2 { + padding-left: 8px; + padding-right: 8px; + text-align: left; + width: 25%; +} + +#debug { + margin-top: 12px; +} + +#debug .tcl { + width: 10%; +} + +#punredirect #debug .tcl, #punmaint #debug .tcl { + width: 20%; +} + +#debug .tcr { + width: 90%; + white-space: normal +} + +#punindex .tcr .byuser { + display: block +} + +#punindex td.tc2, #punindex td.tc3, #punindex td.tcr, .pun #vf td.tc2, .pun #vf td.tc3, +.pun #vf td.tcr, #punindex td.tcl div.forumdesc, .pun #vf td.tcl span { + font-size: 0.923em; +} + +.pun #vf td.tcl a { + font-weight: bold; +} + +.pun #vf td.tcl span a { + font-weight: normal; +} + +.pun .blocktable .tclcon { + height: 1%; + min-height: 1px; + overflow: hidden; + padding: 0 11px 0 12px; + position: relative; +} + +.pun .blocktable .tclcon div { + width: 100%; + overflow: hidden; +} + +.pun .icon { + border-style: solid; + border-width: 8px; + float: left; + height: 0; + overflow: hidden; + width: 0; +} + +.pun .iposted .ipost { + font-weight: bold; + left: 0; + padding-left: 4px; + position: absolute; + text-align: center; + top: 0; + width: 8px; +} + +/***************************************************************** +MAIN POSTS +*****************************************************************/ + +/* Structure +----------------------------------------------------------------*/ + +.pun .blockpost { + border-style: solid; + border-width: 1px; + margin-bottom: -1px; + overflow: hidden; + position: relative; +} + +* html .pun .blockpost { + display: inline-block; +} + +.pun .blockpost h2 { + font: 1em/1.462em Arial, Helvetica, sans-serif; + white-space: nowrap; + border-bottom-style: solid; + border-bottom-width: 1px; + height: 1.462em; + padding: 0.538em 8px 0.538em 236px; + font-weight: normal; +} + +#punsearch .blockpost h2 { + height: auto; + padding-left: 36px; + white-space: normal; +} + +#punsearch .blockpost h2 span span { + white-space: nowrap; + display: inline-block; + font: 1.077em "Trebuchet MS", Arial, Helvetica, sans-serif +} + +#punsearch .blockpost .icon { + position: absolute; + top: 0; + margin-top: -2.154em; +} + +.pun .blockpost h2 .conr { + float: right; + text-align: right; +} + +.pun .blockpost .inbox { + float: right; + position: relative; + width: 100%; +} + +.pun .blockpost .postbody, .pun .blockpost .postfoot { + border-left-style: solid; + border-left-width: 1px; + float: right; + margin-right: -218px; + position: relative; + text-align: left; + width: 100%; +} + +.pun .blockpost .postleft, .pun .blockpost .postfootleft { + width: 206px; + padding: 7px 0 7px 12px; + float: left; + margin-left: -218px; + position: relative; +} + +.pun .blockpost .postleft dl { + padding: 0; +} + +#punviewtopic .blockpost dt, #punmoderate .blockpost dt { + display: block; + position: absolute; + padding: 0.538em 0 0.538em 12px; + height: 1.462em; + top: -2.615em; + left: 0; + overflow: hidden; + width: 206px; +} + +.pun .blockpost dt strong { + font-size: 1.231em; + font-weight: bold; +} + +.pun .blockpost .postleft dd { + font-size: 0.923em; +} + +.pun .blockpost .postleft .usertitle { + padding: 4px 0 6px 0; + font-size: 1em; +} + +.pun .blockpost .postleft .postavatar { + display: block; + margin: 0 0 4px 0; +} + +.pun .blockpost .postright { + position: relative; + padding: 4px 230px 7px 18px; +} + +.pun .postmsg { + width:100%; + overflow: hidden; +} + +.pun .blockpost .postfootright { + position: relative; + padding: 7px 230px 7px 18px; + text-align: right; +} + +.pun .postfoot p, .pun .postfoot ul { + padding: 0; +} + +.pun .blockpost .postfootright li { + display: inline; +} + +.pun .blockpost .postfootright li span { + display: inline-block; + padding-left: 16px; + margin-left: 8px; + line-height: normal; + background: url(Earth/img/bull.png) center left no-repeat; +} + +.pun .blockpost .usercontacts { + padding: 7px 0; +} + +.pun .blockpost .usercontacts .email { + background: url(Earth/img/email.png) left 65% no-repeat; + margin-right: 5px; + padding-left: 21px; + display: inline-block; + line-height: normal; +} + +.pun .blockpost .usercontacts .website { + background: url(Earth/img/ext.png) left 65% no-repeat; + padding-left: 18px; + display: inline-block; + line-height: normal; +} + +.pun .postsignature hr { + border:none; + height: 1px; + margin-left: 0px; + text-align: left; +} + +/* Content (includes other user content) +----------------------------------------------------------------*/ + +.pun .usercontent { + padding: 7px 0; +} + +.pun .postmsg p, .pun .postmsg li, #punhelp p samp { + font-family: Verdana, Arial, Helvetica, sans-serif; +} + +.pun .usercontent h1, .pun .usercontent h2, .pun .usercontent h3, +.pun .usercontent h4, .pun .usercontent h5, .pun .usercontent h6 { + padding: 7px 0 0 0; +} + +.pun .postmsg h5, #punhelp h5 { + font-size: 1.231em; + font-weight: bold; + padding: 7px 0; +} + +.pun .usercontent ul, .pun .postmsg ul { + list-style: disc; + padding: 4px 13px 4px 30px; +} + +.pun .usercontent ol, .pun .postmsg ol { + list-style: decimal; + padding: 4px 13px 4px 30px; +} + +.pun .usercontent ol.alpha, .pun .postmsg ol.alpha { + list-style: lower-alpha; +} + +.pun .usercontent li, .pun .postmsg li { + padding: 0 3px; +} + +.pun .usercontent li p, .pun .postmsg li p { + padding: 0; +} + +.pun span.bbu { + text-decoration: underline; +} + +.pun span.bbs, .pun del { + text-decoration: line-through; +} + +.pun .postmsg ins, #punhelp samp ins { + text-decoration: none; +} + +.pun .blockpost .postmsg .postedit { + font-size: 0.857em; +} + +.pun .blockform .postsignature, .pun .blockpost .postsignature { + font-size: 0.923em; +} + +.pun .codebox { + border-style: solid; + border-width: 1px; + margin: 0.75em 1em; + padding: 0; +} + +.pun .quotebox { + border-style: solid; + border-width: 1px 1px 1px 3px; + margin: 0.75em 1em; + padding: 0 0.75em; +} + +.pun .quotebox cite { + display: block; + padding: 0.75em 0 0 0; + font-weight: bold; + line-height: 1.462em; +} + +.pun .quotebox blockquote { + overflow: hidden; + width: 100%; +} + +.pun .codebox pre { + overflow-y:hidden; + overflow: auto; + width: 100%; + direction: ltr; + text-align: left; +} + +* html .pun .codebox pre { + padding-bottom: 10px; +} + +*:first-child+html .pun .codebox pre { + padding-bottom: 10px; +} + +.pun .codebox pre code { + padding: 0.75em; + white-space: pre; +} + +.pun div[class*=codebox] pre code { + display: inline-block; +} + +* html .pun .codebox pre code { + display: block; +} + +.pun .codebox pre.vscroll { + height: 32em; + overflow: auto; + overflow-y: auto +} + +.pun .postmsg img, #punhelp samp img { + vertical-align: text-top; +} + +.pun .postmsg .postimg img { + max-width: 98%; + vertical-align: middle; +} + +.pun .postmsg .postimg a:link img, .pun .postmsg .postimg a:visited img { + border-style: solid; + border-width: 2px; +} + +/***************************************************************** +MAIN FORMS +*****************************************************************/ + +#punedit .blockform h2, #punpost .blockform h2, #postpreview h2, #posterror h2, +.pun #quickpost h2, .pun #reportform h2, #pundelete .blockform h2 { + font: 1em/1.462em Arial, Helvetica, sans-serif; + font-weight: bold; + white-space: nowrap; + padding: 10px 19px 4px 37px; + border: 0; +} + +#punpost .blockform h2, #punedit .blockform h2,.pun #quickpost h2, +#pundelete .blockform h2 { + margin: 1px 1px 0 1px; + width: 25em; + position: absolute; + z-index: 100; +} + +.pun #quickpost legend, #punpost legend, #punedit legend { + width: 25em; + overflow: hidden; + white-space: nowrap; +} + +.pun .blockform .box { + border-style: solid; + border-width: 1px; + padding-bottom: 12px; +} + +.pun #posterror { + border-style: solid; + border-width: 1px; +} + +.pun #posterror .box { + padding: 0 18px 12px 18px; +} + +* html .pun .blockform .box, * html .pun #posterror { + display: inline-block; +} + +.pun .blockform .forminfo, .pun .error-info { + padding: 12px 18px; + border-style: solid; + border-width: 1px; + position: relative; +} + +.pun .blockform .forminfo { + margin-top: 12px; +} + +#pundelete .blockform .forminfo { + margin-top: 33px; +} + +.pun .forminfo h3 { + padding-bottom: 0; +} + +.pun .error-list li { + padding-left: 24px; + background: url(Earth/img/exclaim.png) center left no-repeat; +} + +.pun .inform { + padding: 0 18px; +} + +.pun legend { + font-weight: bold; + padding: 10px 19px 4px 19px; +} + +* html .pun legend { + margin-left: -7px; +} + +*:first-child+html .pun legend { + margin-left: -7px; +} + +.pun .infldset { + border-style: solid; + border-width: 1px; + padding: 12px 18px; +} + +#punregister #rules .infldset { + padding: 5px 18px; +} + +.pun fieldset p { + padding: 0 0 7px 0; + width: 100%; +} + +.pun fieldset .usercontent p { + padding: 7px 0; +} + +.pun fieldset label { + display: block; + padding: 0 0 7px 0; +} + +.pun label em { + font-weight: normal; + font-style: normal; +} + +.pun .required strong { + background: url(Earth/img/asterisk.png) center right no-repeat; + font-weight: normal; + padding-right: 14px; + white-space: pre; + display: inline-block; + line-height: normal; +} + +.pun label input, .pun label select, .pun label textarea { + margin-top: 2px; +} + +.pun label.conl { + display: inline-block; + padding-right: 12px; +} + +.pun form .buttons { + padding: 8px 19px 8px 34px; + margin-bottom: -12px; +} + +.pun .blockform .buttons input { + margin-right: 12px; +} + +.pun .rbox { + padding: 3px 0; +} + +.pun .rbox label { + padding: 3px 0 3px 1.75em; + position: relative; + min-height: 1px; +} + +* html .pun .rbox label { + text-indent: -3px; + height: 1%; +} + +.pun .rbox input { + margin: 3px 0.75em 3px -1.75em; + float: left; + position: relative; + vertical-align: middle; + padding: 0; + height: 1em; + width: 1em; +} + +.pun input[type=text], .pun select, .pun textarea { + font-family: Verdana, Arial, Helvetica, sans-serif; +} + +.pun .txtarea textarea, .pun input.longinput { + width: 98%; +} + +.pun #quickpost .txtarea { + padding-right: 12px; + padding-left: 200px; + position: relative; +} + +.pun .blockform .bblinks { + padding-top: 0; +} + +.pun .blockform .bblinks li { + display: inline; +} + +.pun .blockform .bblinks li span { + background: url(Earth/img/help.png) center left no-repeat; + margin-right: 8px; + padding-left: 20px; + display: inline-block; +} + +.pun #quickpost .bblinks { + left: 18px; + line-height: 1.75em; + position:absolute; + top: 18px; + width: 12em; +} + +.pun #quickpost .bblinks li { + display: block; +} + +.pun #login p.clearb { + border-top-style: dotted; + border-top-width: 1px; + font-size: 0; + height: 0; + line-height: 0; + margin-top: 7px; + overflow: hidden; + padding-bottom: 3px; + padding-top: 7px; + text-indent: -9999em; + width: 100%; +} + +.pun #postreview { + padding-top: 12px; +} + +.pun #postpreview, .pun #posterror { + margin-bottom: 12px; +} + +.pun #postpreview .postright { + padding: 0; +} + +.pun #postpreview .postbody { + border-style: solid; + border-width: 1px; + float: none; + margin: 0 18px 12px 18px; + padding: 0; + padding: 4px 18px 4px 18px; + width: auto; +} + +.pun span.email { + background: url(Earth/img/email.png) left 65% no-repeat; + margin-right: 5px; + padding-left: 21px; + display: inline-block; + line-height: normal; +} + +.pun span.website { + background: url(Earth/img/ext.png) left 65% no-repeat; + padding-left: 18px; + display: inline-block; + line-height: normal; +} + +#punmisc #rules .box { + border-style: solid; + border-width: 1px; + padding: 5px 18px; +} + + +#punhelp .box { + border-style: solid; + border-width: 1px; + padding: 7px 12px; +} + +/***************************************************************** +PROFILES (+ ADMIN MENU) +*****************************************************************/ + +/* Profile / Admin +----------------------------------------------------------------*/ + +.pun .blockmenu { + width: 13em; + float: left; + padding-bottom: 12px; +} + +.pun .block2col .blockform, .pun .block2col .block { + margin-left: 15em; +} + +.pun .blockmenu .block2 { + padding-top: 19px; +} + +.pun .blockmenu ul { + border-top-style: dotted; + border-top-width: 1px; + padding: 0; +} + +.pun .blockmenu li { + border-bottom-style: dotted; + border-bottom-width: 1px; + font-weight: bold; + padding: 0; +} + +.pun .blockmenu a:link, .pun .blockmenu a:visited { + display: block; + padding: 9px 6px 3px 6px; + min-height: 1px; + text-decoration: none; +} + +* html .pun .blockmenu a:link, * html .pun .blockmenu a:visited { + height: 1%; +} + +.pun .blockmenu a:hover, .pun .blockmenu a:active, .pun .blockmenu a:focus { + text-decoration: none; +} + +#viewprofile .box { + border-style: solid; + border-width: 1px; + padding-bottom: 18px; +} + +#viewprofile dt, #adstats dt { + padding: 7px 0; + position: absolute; + width: 13em; + left: 0; +} + +#viewprofile dl { + border-style: solid none none none; + border-width: 1px; + margin: 7px 0; + padding: 0; + width: 100%; + position: relative; +} + +#adintro, #adstats { + border-style: solid; + border-width: 1px; + padding: 18px; +} + +#adstats .inbox, #adintro .inbox { + border-style: solid; + border-width: 1px; + padding: 18px; +} + +#adstats dl { + margin: 0; + padding: 0; + width: 100%; + position: relative; +} + +#viewprofile dd, #adstats dd { + border-style: none none solid none; + border-width: 1px; + padding: 7px 0 7px 13em; +} + +/***************************************************************** +COLOUR SCHEME +*****************************************************************/ + +/* Basic defaults and Common Items +----------------------------------------------------------------*/ + +html, body, .pun { + background: #eaede2; + color: #333; +} + +.pun .punwrap { + background: #fff; + border-color: #ccd7c1; + color: #526550; +} + +#brdtitle #brddesc, .pun .pagepost, #brdstats #onlinelist, #brdfooter #searchlinks, #brdfooter #modcontrols, +#punmaint h2, #punredirect h2, #adminconsole .submittop, .pun #debugtime, .pun .pagelink a, .pun .pagelink * { + border-color: #bbc6b2; +} + +.pun a, .pun a:link, .pun a:visited { + color: #047E00; +} + +.pun a:hover, .pun a:active, .pun a:focus { + color: #73A900; +} + +.pun .postmsg .postimg a:link img, .pun .postmsg .postimg a:visited img { + border-color: #047E00; +} + +.pun .postmsg .postimg a:hover img, .pun .postmsg .postimg a:active img, .pun .postmsg .postimg a:focus img { + border-color: #73A900; +} + +/* Primary Navigation +----------------------------------------------------------------*/ + +#brdmenu { + background: #32671d; +} + +#brdmenu a, #brdmenu a:link, #brdmenu a:visited { + background: #32671d; + border-color: #fff; + color: #e3e3c8; +} + +#brdmenu a:hover, #brdmenu a:active, #brdmenu a:focus { + background: #2ca100; + border-color: #fff; + color: #fff; +} + +/* Main Tables +----------------------------------------------------------------*/ + +.pun .blocktable .box { + background: #fcfcf4; + border-color: #bbc6b2 #d8dccf; +} + +#punindex .blocktable h2, .pun #vf h2 { + color: #83866a; +} + +#adminconsole fieldset th, #adminconsole fieldset td { + background: #f6f6ea; + border-color: #dce6d8; +} + +.pun #users1 h2 { + background: #fff; +} + +.pun .blocktable td { + border-color: #dce6d8; +} + +.pun .blocktable th { + background: #eaecda; + border-color: #ccd7c1; + color: #83866a; +} + +.pun .blocktable td.tcl span.stickytext { + color: #c08b20; +} + +/* Main Posts +----------------------------------------------------------------*/ + +.pun .blockpost { + background: #f6f6ea; + border-color: #bbc6b2 #d8dccf; +} + +.pun .blockpost h2 { + background: #eaecda; + border-color: #ccd7c1; + color: #83866a; +} + +.pun .blockpost .postbody, .pun .blockpost .postfoot { + background: #fcfcf4; + border-color: #dce6d8; +} + +.pun .blockpost .postfootright li { + color: #fcfcf4; +} + +.pun .postmsg, #punhelp code, #punhelp samp { + color: #333; +} + +.pun .postsignature, .pun .postmsg .postedit { + color: #526550; +} + +.pun .quotebox { + background: #f9fae5; + border-color: #bdbc7a; + color: #566579; +} + +.pun .quotebox cite { + color: #83866a; +} + +.pun .codebox, #punhelp .codebox code { + background: #333; + color: #fff; +} + +.pun .postmsg hr { + background: #bbc6b2; +} + +.pun .postmsg ins, #punhelp samp ins { + background-color: #ff0; +} + +/* Main Forms + Profile +----------------------------------------------------------------*/ + +.pun .blockform .box, #adstats, #adintro, #postpreview, #posterror { + border-color: #bbc6b2 #d8dccf; + background: #eaecda; +} + +#punmisc #rules .box, #punhelp .box { + border-color: #bbc6b2 #d8dccf; + background: #f6f6ea; +} + +.pun #quickpost h2, #punpost .blockform h2, #punedit .blockform h2, #posterror h2, +#pundelete .blockform h2 { + background: #eaecda; + color: #83866a; +} + +.pun .forminfo { + background: #fff; + border-color: #dce6d8; +} + +#puninstall form#install .forminfo { + background: #32671d; + color: #fff; +} + +.pun #posterror .error-info { + background: #ffffe1; + border-color: #dfe6ee; +} + +#puninstall form#install .error-info { + background: #ffffe1; + border-color: #dfe6ee; + color: #333; +} + +.pun .infldset, #adintro .inbox, #adstats .inbox { + background: #f6f6ea; + border-color: #dce6d8; +} + +.pun label, .pun legend, #adminconsole fieldset th { + color: #83866a; +} + +.pun fieldset p { + border-color: #bbc6b2; +} + +.pun .blockmenu ul, .pun .blockmenu li { + border-color: #bbc6b2; +} + +.pun .blockmenu a:hover, .pun .blockmenu a:active, .pun .blockmenu a:focus { + background: #ffffe6; +} + +.pun .blockmenu .isactive a:link, .pun .blockmenu .isactive a:visited { + color: #333; + background: #f6f6ea; + } + +.pun #viewprofile .box { + border-color: #bbc6b2 #d8dccf; + background: #eaecda; +} + +.pun #viewprofile dt, #adstats dt { + color: #83866a; +} + +.pun #viewprofile dl, .pun #viewprofile dd, #adstats dl, #adstats dd { + border-color: #dce6d8; +} + +#adminconsole fieldset td.nodefault { + background: #d59b9b; +} + +/* Status Indicators +----------------------------------------------------------------*/ + +.pun .icon { + border-color: #eef1e8 #dbddd4 #e6e8df #eef1e8; +} + +.pun .iredirect .icon { + border-color: #bbc6b2; + border-width: 1px; + padding: 7px; +} + +.pun .inew .icon { + border-color: #50a42f #408426 #32671d #4a982c; +} diff --git a/style/Earth/base_admin.css b/style/Earth/base_admin.css new file mode 100644 index 0000000..66bfe2c --- /dev/null +++ b/style/Earth/base_admin.css @@ -0,0 +1,144 @@ +#adminconsole .blockform .box { + padding-bottom: 12px; +} + +#adminconsole fieldset .infldset { + position: relative; + overflow: hidden; +} + +#adminconsole fieldset table { + margin-top: -1px; + margin-bottom: -1px; +} + +#adminconsole fieldset td, #adminconsole fieldset th { + padding: 10px 8px 10px 0; + text-align: left; + white-space: normal; + border-style: solid none; + border-width: 1px 0; +} + +#punadmin thead th { + border-top: 0; + font-weight: normal; +} + +#adminconsole fieldset td span, #adminconsole fieldset th span { + display: block; font-size: 1em; + font-weight: normal; +} + +#adminconsole fieldset td.location span { + display: inline-block; +} + +#adminconsole fieldset tbody th { + width: 15em; + font-weight: normal; + padding-right: 8px; +} + +#adminconsole table.aligntop th, #adminconsole table.aligntop td { + vertical-align: top; +} + +#adminconsole table.aligntop th div { + padding-top: 3px; +} + +#adminconsole .inform { + padding-bottom: 0; +} + +#adminconsole .infldset { + padding-bottom: 0; + padding-top: 0; +} + +#adminconsole p.submittop { + text-align: center; + border-bottom-style: dotted; + border-bottom-width: 1px; + margin: 0 18px; + padding-top: 12px; +} + +#adminconsole p.submitend { + text-align: center; + padding-bottom: 0; +} + +#adminconsole fieldset p { + padding: 10px 0; +} + +#adminconsole .fsetsubmit { + padding: 10px 0 12px 0; +} + +#categoryedit .tcl { + width: 25%; +} + +#censoring .tcl, #censoring .tc2, #ranks .tcl, #ranks .tc2 { + width: 20%; +} + +#edforum .tcl { + width: 18%; +} + +#edforum .tc2 { + width: 12%; +} + +#forumperms thead th, #forumperms tbody td { + text-align: center; +} + +.pun .linkst .backlink, .pun .linksb .backlink { + padding: 7px 0; +} + +#punadmin #users1 h2, #punadmin #users2 h2, #punadmin #bans1 h2 { + display: block; + left: -9999em; + overflow: hidden; + position: absolute; + text-indent: -9999em; + width: 0; +} + +#punadmin #users1 th, #punadmin #users2 th, #punadmin #bans1 th { + font-weight: bold; + } + +#users2 th, #bans1 th { + text-align: left; +} + +#users2 .tcl, #users2 .tc3, #users2 .tc5, #bans1 .tcl, #bans1 .tc3, #bans1 .tc5, #bans1 .tc6 { + width: 15%; + text-align: left; +} + +#users2 .tc2, #bans1 .tc2 { + width: 22%; + text-align: left; +} + +#users2 .tc4, #bans1 .tc4 { + width: 8%; + text-align: center; +} + +#users2 .tcr, #bans1 .tcr { + white-space: nowrap; +} + +#exampleplugin p { + padding-left: 18px; + padding-right: 18px; +} \ No newline at end of file diff --git a/style/Earth/img/asterisk.png b/style/Earth/img/asterisk.png new file mode 100644 index 0000000..d00ef54 Binary files /dev/null and b/style/Earth/img/asterisk.png differ diff --git a/style/Earth/img/bull.png b/style/Earth/img/bull.png new file mode 100644 index 0000000..5fd1a9a Binary files /dev/null and b/style/Earth/img/bull.png differ diff --git a/style/Earth/img/email.png b/style/Earth/img/email.png new file mode 100644 index 0000000..bd1ee24 Binary files /dev/null and b/style/Earth/img/email.png differ diff --git a/style/Earth/img/exclaim.png b/style/Earth/img/exclaim.png new file mode 100644 index 0000000..92eb57b Binary files /dev/null and b/style/Earth/img/exclaim.png differ diff --git a/style/Earth/img/ext.png b/style/Earth/img/ext.png new file mode 100644 index 0000000..1e4a0b2 Binary files /dev/null and b/style/Earth/img/ext.png differ diff --git a/style/Earth/img/feed.png b/style/Earth/img/feed.png new file mode 100644 index 0000000..d4cf8ce Binary files /dev/null and b/style/Earth/img/feed.png differ diff --git a/style/Earth/img/help.png b/style/Earth/img/help.png new file mode 100644 index 0000000..9b9114d Binary files /dev/null and b/style/Earth/img/help.png differ diff --git a/style/Earth/img/index.html b/style/Earth/img/index.html new file mode 100644 index 0000000..89337b2 --- /dev/null +++ b/style/Earth/img/index.html @@ -0,0 +1 @@ +.. diff --git a/style/Earth/img/main_end.png b/style/Earth/img/main_end.png new file mode 100644 index 0000000..c9d5659 Binary files /dev/null and b/style/Earth/img/main_end.png differ diff --git a/style/Earth/img/main_top.png b/style/Earth/img/main_top.png new file mode 100644 index 0000000..787718f Binary files /dev/null and b/style/Earth/img/main_top.png differ diff --git a/style/Earth/index.html b/style/Earth/index.html new file mode 100644 index 0000000..89337b2 --- /dev/null +++ b/style/Earth/index.html @@ -0,0 +1 @@ +.. diff --git a/style/Fire.css b/style/Fire.css new file mode 100644 index 0000000..ad74a58 --- /dev/null +++ b/style/Fire.css @@ -0,0 +1,1601 @@ +/***************************************************************** +1. INITIAL SETTINGS +*****************************************************************/ + +/* Limited Reset +----------------------------------------------------------------*/ + +html, body, .pun table, .pun div, .pun form, .pun p, .pun h1, .pun h2, .pun h3, .pun h4, .pun h5, .pun pre, .pun blockquote, +.pun ul, .pun ol, .pun li, .pun dl, .pun dt, .pun dd, .pun th, .pun td, .pun fieldset, .pun legend .pun img, +.pun abbr, .pun cite { + border: 0; + font-style: normal; + font-weight: normal; + margin: 0; + padding: 0; +} + +.pun ul, .pun ol { + list-style: none; +} + +.pun select { + padding-bottom: 1px; + padding-top: 1px; +} + +/* Content Defaults +----------------------------------------------------------------*/ + +.pun { + font: 81.25%/1.462em Arial, Helvetica, sans-serif; +} + +.pun table, .pun td, .pun th, .pun input, .pun select, .pun optgroup, .pun textarea { + font-family: Arial, Helvetica, sans-serif; + font-size: 1em; +} + +.pun pre, .pun code { + font-family: consolas, monaco, "bitstream vera sans mono", "courier new", courier, monospace; + font-size: 1em; +} + +.pun pre code { + font-size: 1em; +} + +.pun table { + border-collapse: collapse; + border-spacing: 0; + border: 0; + empty-cells: show; + width: 100%; +} + +.pun h1 { + font:2.154em/1em "Trebuchet MS", Arial, Helvetica, sans-serif; + padding: 7px 0; +} + +.pun h2, .pun .hd h2 { + font: 1.462em/1em "Trebuchet MS", Arial, Helvetica, sans-serif; + padding: 7px 0; +} + +.pun h3 { + font-size: 1.154em; + line-height: 1.267em; + padding: 7px 0; +} + +.pun h4 { + font-size: 1.077em; + font-weight: bold; + padding: 7px 0; +} + +.pun h5, .pun h6 { + font-size: 1em; + font-weight: bold; + padding: 7px 0; +} + +.pun p, .pun ul, .pun ol, .pun dl, .pun th, .pun td, .pun legend { + padding: 7px 0; +} + +.pun strong, .pun th, .pun span.warntext, .pun p.warntext { + font-weight: bold; +} + +.pun em { + font-style: italic; +} + +.pun a, .pun a:link, .pun a:visited { + text-decoration: none; +} + +.pun a:hover, .pun a:active, .pun a:focus { + text-decoration: underline; +} + +.pun .actions span { + padding-left: 16px; + padding-right: 8px; + background: url(Fire/img/bull.png) center left no-repeat; + display: inline-block; + line-height: normal; +} + +/* Hidden Elements +----------------------------------------------------------------*/ + +#brdfooter h2, #brdstats h2, #debug h2, #brdstats .conl dt, #brdstats .conr dt, #modcontrols dt, +#searchlinks dt, div.postright h3, .pun .subscribelink span, #announce .hd, #reportform h2, #punmoderate #vf h2, +#punviewforum #vf h2, .pun .required strong span, .pun .icon div { + display: block; + overflow: hidden; + position: absolute; + text-indent: -9999em; + width: 0; +} + +/* Generic Float Clear +----------------------------------------------------------------*/ + +.pun .inbox, .pun #brdmain, .pun .crumbs, .pun .pagepost, .pun .block2col { + min-height: 1px; +} + +* html .pun .inbox, * html .pun #brdmain, * html .pun .infldset, * html .pun .crumbs, * html .pun .pagepost, * html .pun .block2col { + display: inline-block; +} + +* html .pun .inbox, * html .pun #bdrdmain, * html .pun .infldset, * html .pun .crumbs, * html .pun .pagepost, * html .pun .block2col { + display: block; +} + +.pun .inbox:after, .pun #brdmain:after, .pun .crumbs:after, .pun .pagepost:after, .pun .block2col:after { + content: " "; + display: block; + height: 0; + font-size: 0; + clear: both; + visibility: hidden; +} + +.pun .block2col .inbox:after { + content: none; + clear: none; +} + +/***************************************************************** +2. COMMON STYLES +*****************************************************************/ + +/* Page Layout +----------------------------------------------------------------*/ + +.pun { + padding: 30px 40px; +} + +#punredirect, #punmaint { + padding: 60px 20% 12px 20%; +} + +#puninstall, #pundb_update { + padding: 20px 10%; +} + +.pun .punwrap { + border: 1px solid; + padding: 18px; +} + +.pun .top-box { + height: 18px; + margin-bottom: -18px; + position: relative; + background: url(Fire/img/main_top.png) top left no-repeat; +} + +.pun .top-box div { + height: 18px; + margin-left: 50%; + background: url(Fire/img/main_top.png) top right no-repeat; +} + +.pun .end-box { + margin-top: -17px; + height: 18px; + position: relative; + background: url(Fire/img/main_end.png) bottom left no-repeat; +} + +.pun .end-box div { + height: 18px; + margin-left: 50%; + background: url(Fire/img/main_end.png) bottom right no-repeat; +} + +#punredirect h2, #punmaint h2 { + border-bottom-style: dotted; + border-bottom-width: 1px; + margin-bottom: 3px; +} + +/* Section Spacing and Borders +----------------------------------------------------------------*/ + +#brdmain { + border-style: solid none; + border-width: 2px 0; + margin-bottom: 12px; + padding: 12px 0; +} + +#punindex #brdmain { + padding-top: 24px; +} + +#punredirect #brdmain, #punmaint #brdmain { + border: 0; + margin: 0; + padding: 0; +} + +#brdstats { + border-style: solid none none none; + border-width: 2px 0 0 0; + margin-top: 24px; + padding-top: 12px; +} + +#quickpost { + border-style: solid none none none; + border-width: 2px 0 0 0; + margin-top: 12px; + padding-top: 12px; +} + +#announce { + border-style: solid none none none; + border-width: 2px 0 0 0; + padding-top: 3px; +} + +/***************************************************************** +3. COMMON BOARD ELEMENTS +*****************************************************************/ + +/* Logo, Description and Main Menu +----------------------------------------------------------------*/ + +#brdtitle h1 { + padding: 0 0 10px 0; +} + +#brddesc { + border-top-style: dotted; + border-top-width: 1px; + padding: 10px 0; +} + +#brddesc p { + padding: 0; +} + +#brdmenu ul { + padding: 0; +} + +#brdmenu li { + float: left; +} + +#brdmenu a:link, #brdmenu a:visited { + border-right-style: solid; + border-width: 1px; + display: inline-block; + min-width: 60px; + padding: 12px 16px 6px 8px; + white-space: nowrap; +} + +#brdmenu a:hover, #brmenu a:active, #brdmenu a:focus { + text-decoration: none; +} + +/* Welcome Box +----------------------------------------------------------------*/ + +#brdwelcome { + padding: 10px 0; +} + +#brdwelcome .conl, #brdwelcome .conr, #brdwelcome p, #brdwelcome li { + display: inline; + padding: 0; +} + +#brdwelcome li span { + background: url(Fire/img/bull.png) center left no-repeat; + padding-left: 18px; + margin-right: 3px; + display: inline-block; + line-height: normal; + white-space: nowrap; +} + +#brdwelcome .conl li:first-child span { + padding-left: 0; + background: none; +} + +/* Stats +----------------------------------------------------------------*/ + +#brdstats .conl { + float: left; +} + +#brdstats .conr { + float: right; + text-align: right; +} + +#brdstats #onlinelist { + border-top-style: dotted; + border-top-width: 1px; + clear: both; +} + +#brdstats #onlinelist dt, #brdstats #onlinelist dd { + display: inline; +} + +/* Footer +----------------------------------------------------------------*/ + +.pun #modcontrols { + border-style: none none dotted none; + border-width: 0 0 1px 0; + margin-bottom: 4px; + text-align: center; + width: 100%; +} + +.pun #modcontrols dd { + display: inline; +} + +.pun #brdfooter #modcontrols dd span { + background: url(Fire/img/bull.png) center left no-repeat; + display: inline-block; + line-height: normal; + padding-left: 18px; + white-space: nowrap; +} + +.pun #brdfooter .conl { + float: left; +} + +.pun #brdfooter .conr { + text-align: right; + float: right; +} + +.pun #brdfooter #poweredby a { + font-size: 1.077em; + font-weight: bold; +} + +.pun #brdfooter #qjump { + padding-top: 5px; +} + +.pun #brdfooter #qjump * { + white-space: nowrap; +} + +.pun #brdfooter #searchlinks dd span { + background: url(Fire/img/bull.png) center left no-repeat; + display: inline-block; + line-height: normal; + padding-left: 18px; + white-space: nowrap; +} + +.pun #brdfooter #feedlinks { + padding-bottom: 0; +} + +.pun #brdfooter #feedlinks span { + background: url(Fire/img/feed.png) center left no-repeat; + display: inline-block; + padding-left: 18px; + white-space: nowrap; +} + +.pun #debugtime { + border-style: dotted none none none; + border-width: 1px 0 0 0; + margin-top: 7px; + text-align: center; +} + +/* Breadcrumbs, Postlink, Pagination +----------------------------------------------------------------*/ + +.pun .linkst .inbox, .pun linksb .inbox, .pun .postlinksb .inbox { + overflow: hidden; +} + +.pun .linksb, .pun .postlinksb, .pun .linkst, .pun .crumbs { + clear: both; + position: relative; +} + +.pun .linkst .crumbs { + font-family: "Trebuchet MS", Helvetica, Arial, sans-serif; + font-size: 1.462em; + line-height: 1.211em; + padding: 7px 0; +} + +.pun .linksb .crumbs, .pun .postlinksb .crumbs { + font-family: "Trebuchet MS", Helvetica, Arial, sans-serif; + font-size: 1.154em; +} + +.pun .linkst .crumbsplus .pagepost { + border-top-style: dotted; + border-top-width: 1px; +} + +.pun .linksb .crumbsplus .pagepost, .pun .postlinksb .crumbsplus .pagepost { + border-bottom-style: dotted; + border-bottom-width: 1px; +} + +.pun .postlinksb .crumbs { + margin-right: 11em; +} + +.pun .crumbs li { + float: left; + padding-right: 0.4em; + white-space: nowrap; +} + +.pun .crumbs li strong { + font-weight: normal; +} + +.pun .pagelink { + float: left; + white-space: nowrap; +} + +.pun .pagelink strong, .pun .pagelink a, .pun .pagelink span.spacer { + border-style: none none none solid; + border-width: 0 0 0 1px; + display: inline-block; + padding: 0 12px 0 10px; + margin-right: -6px; +} + +.pun .pagelink .item1 { + border: 0; +} + +.pun .pagelink .pages-label { + display: inline-block; +} + +.pun .postlink { + float: right; + font-weight: bold; + text-align: right; +} + +.pun .modbuttons { + float: right; + padding: 5px 0 3px 0; +} + +.pun .modbuttons input { + margin-left: 8px; +} + +.pun .subscribelink { + position: absolute; + right: 0; + text-align: right; + top: 33px; +} + +/***************************************************************** +4. MAIN TABLES +*****************************************************************/ + +#punindex #brdmain .blocktable h2, #punsearch #vf h2 { + font: 1em/1.462em Arial, Helvetica, sans-serif; + font-weight: bold; + margin: 1px 1px 0 1px; + padding-left: 8px; + position: absolute; + white-space: nowrap; + z-index: 100; +} + +#punindex .blocktable th.tcl, #punsearch #vf th.tcl { + font-size: 0; + text-indent: -9999em; +} + +.pun .blocktable .box { + border-style: solid; + border-width: 1px; + margin-bottom: -1px; + overflow: hidden; + position: relative; +} + +* html .pun .blocktable .box { + display: inline-block; +} + +.pun .blocktable table { + table-layout: fixed; + margin-bottom: -1px; +} + +.pun .blocktable th { + padding: 7px 8px; + border-style: none none solid none; + border-width: 1px; + text-align: left; +} + +.pun .blocktable td { + padding: 7px 8px; + line-height: 1.3077em; + border-style: none none solid none; + border-width: 1px; + text-align: left; +} + +.pun .blocktable h3 { + font-size: 1.077em; + font-weight: bold; + padding: 0; +} + +.pun .blocktable p { + padding: 0; +} + +.pun .blocktable .tcl p { + padding: 5px 0 0 0; +} + +.pun .blocktable .tcl { + width: auto; +} + +.pun .blocktable .tc2, .pun .blocktable .tc3, .pun .blocktable .tcmod { + padding-left: 0; + padding-right: 0; + text-align: center; + width: 11%; +} + +.pun .blocktable .tcr { + width: 30%; +} + +.pun .blocktable td .newtext, .pun .blocktable td .pagestext, .pun .blocktable td .byuser { + white-space: nowrap; +} + +.pun .blocktable .tcl h3 span.newtext { + font-size: 0.929em; + font-weight: normal; +} + +.pun #vf td.tcl span.stickytext, .pun #vf td.tcl span.closedtext { + font-size: 1em; + font-weight: bold; +} + +#punsearch #vf .tc2 { + padding-left: 8px; + padding-right: 8px; + text-align: left; + width: 18%; +} + +#users1 .tcr { + width: 25%; +} + +#users1 .tc2 { + padding-left: 8px; + padding-right: 8px; + text-align: left; + width: 25%; +} + +#debug { + margin-top: 12px; +} + +#debug .tcl { + width: 10%; +} + +#punredirect #debug .tcl, #punmaint #debug .tcl { + width: 20%; +} + +#debug .tcr { + width: 90%; + white-space: normal +} + +#punindex .tcr .byuser { + display: block +} + +#punindex td.tc2, #punindex td.tc3, #punindex td.tcr, .pun #vf td.tc2, .pun #vf td.tc3, +.pun #vf td.tcr, #punindex td.tcl div.forumdesc, .pun #vf td.tcl span { + font-size: 0.923em; +} + +.pun #vf td.tcl a { + font-weight: bold; +} + +.pun #vf td.tcl span a { + font-weight: normal; +} + +.pun .blocktable .tclcon { + height: 1%; + min-height: 1px; + overflow: hidden; + padding: 0 11px 0 12px; + position: relative; +} + +.pun .blocktable .tclcon div { + width: 100%; + overflow: hidden; +} + +.pun .icon { + border-style: solid; + border-width: 8px; + float: left; + height: 0; + overflow: hidden; + width: 0; +} + +.pun .iposted .ipost { + font-weight: bold; + left: 0; + padding-left: 4px; + position: absolute; + text-align: center; + top: 0; + width: 8px; +} + +/***************************************************************** +MAIN POSTS +*****************************************************************/ + +/* Structure +----------------------------------------------------------------*/ + +.pun .blockpost { + border-style: solid; + border-width: 1px; + margin-bottom: -1px; + overflow: hidden; + position: relative; +} + +* html .pun .blockpost { + display: inline-block; +} + +.pun .blockpost h2 { + font: 1em/1.462em Arial, Helvetica, sans-serif; + white-space: nowrap; + border-bottom-style: solid; + border-bottom-width: 1px; + height: 1.462em; + padding: 0.538em 8px 0.538em 236px; + font-weight: normal; +} + +#punsearch .blockpost h2 { + height: auto; + padding-left: 36px; + white-space: normal; +} + +#punsearch .blockpost h2 span span { + white-space: nowrap; + display: inline-block; + font: 1.077em "Trebuchet MS", Arial, Helvetica, sans-serif +} + +#punsearch .blockpost .icon { + position: absolute; + top: 0; + margin-top: -2.154em; +} + +.pun .blockpost h2 .conr { + float: right; + text-align: right; +} + +.pun .blockpost .inbox { + float: right; + position: relative; + width: 100%; +} + +.pun .blockpost .postbody, .pun .blockpost .postfoot { + border-left-style: solid; + border-left-width: 1px; + float: right; + margin-right: -218px; + position: relative; + text-align: left; + width: 100%; +} + +.pun .blockpost .postleft, .pun .blockpost .postfootleft { + width: 206px; + padding: 7px 0 7px 12px; + float: left; + margin-left: -218px; + position: relative; +} + +.pun .blockpost .postleft dl { + padding: 0; +} + +#punviewtopic .blockpost dt, #punmoderate .blockpost dt { + display: block; + position: absolute; + padding: 0.538em 0 0.538em 12px; + height: 1.462em; + top: -2.615em; + left: 0; + overflow: hidden; + width: 206px; +} + +.pun .blockpost dt strong { + font-size: 1.231em; + font-weight: bold; +} + +.pun .blockpost .postleft dd { + font-size: 0.923em; +} + +.pun .blockpost .postleft .usertitle { + padding: 4px 0 6px 0; + font-size: 1em; +} + +.pun .blockpost .postleft .postavatar { + display: block; + margin: 0 0 4px 0; +} + +.pun .blockpost .postright { + position: relative; + padding: 4px 230px 7px 18px; +} + +.pun .postmsg { + width:100%; + overflow: hidden; +} + +.pun .blockpost .postfootright { + position: relative; + padding: 7px 230px 7px 18px; + text-align: right; +} + +.pun .postfoot p, .pun .postfoot ul { + padding: 0; +} + +.pun .blockpost .postfootright li { + display: inline; +} + +.pun .blockpost .postfootright li span { + display: inline-block; + padding-left: 16px; + margin-left: 8px; + line-height: normal; + background: url(Fire/img/bull.png) center left no-repeat; +} + +.pun .blockpost .usercontacts { + padding: 7px 0; +} + +.pun .blockpost .usercontacts .email { + background: url(Fire/img/email.png) left 65% no-repeat; + margin-right: 5px; + padding-left: 21px; + display: inline-block; + line-height: normal; +} + +.pun .blockpost .usercontacts .website { + background: url(Fire/img/ext.png) left 65% no-repeat; + padding-left: 18px; + display: inline-block; + line-height: normal; +} + +.pun .postsignature hr { + border:none; + height: 1px; + margin-left: 0px; + text-align: left; +} + +/* Content (includes other user content) +----------------------------------------------------------------*/ + +.pun .usercontent { + padding: 7px 0; +} + +.pun .postmsg p, .pun .postmsg li, #punhelp p samp { + font-family: Verdana, Arial, Helvetica, sans-serif; +} + +.pun .usercontent h1, .pun .usercontent h2, .pun .usercontent h3, +.pun .usercontent h4, .pun .usercontent h5, .pun .usercontent h6 { + padding: 7px 0 0 0; +} + +.pun .postmsg h5, #punhelp h5 { + font-size: 1.231em; + font-weight: bold; + padding: 7px 0; +} + +.pun .usercontent ul, .pun .postmsg ul { + list-style: disc; + padding: 4px 13px 4px 30px; +} + +.pun .usercontent ol, .pun .postmsg ol { + list-style: decimal; + padding: 4px 13px 4px 30px; +} + +.pun .usercontent ol.alpha, .pun .postmsg ol.alpha { + list-style: lower-alpha; +} + +.pun .usercontent li, .pun .postmsg li { + padding: 0 3px; +} + +.pun .usercontent li p, .pun .postmsg li p { + padding: 0; +} + +.pun span.bbu { + text-decoration: underline; +} + +.pun span.bbs, .pun del { + text-decoration: line-through; +} + +.pun .postmsg ins, #punhelp samp ins { + text-decoration: none; +} + +.pun .blockpost .postmsg .postedit { + font-size: 0.857em; +} + +.pun .blockform .postsignature, .pun .blockpost .postsignature { + font-size: 0.923em; +} + +.pun .codebox { + border-style: solid; + border-width: 1px; + margin: 0.75em 1em; + padding: 0; +} + +.pun .quotebox { + border-style: solid; + border-width: 1px 1px 1px 3px; + margin: 0.75em 1em; + padding: 0 0.75em; +} + +.pun .quotebox cite { + display: block; + padding: 0.75em 0 0 0; + font-weight: bold; + line-height: 1.462em; +} + +.pun .quotebox blockquote { + overflow: hidden; + width: 100%; +} + +.pun .codebox pre { + overflow-y:hidden; + overflow: auto; + width: 100%; + direction: ltr; + text-align: left; +} + +* html .pun .codebox pre { + padding-bottom: 10px; +} + +*:first-child+html .pun .codebox pre { + padding-bottom: 10px; +} + +.pun .codebox pre code { + padding: 0.75em; + white-space: pre; +} + +.pun div[class*=codebox] pre code { + display: inline-block; +} + +* html .pun .codebox pre code { + display: block; +} + +.pun .codebox pre.vscroll { + height: 32em; + overflow: auto; + overflow-y: auto +} + +.pun .postmsg img, #punhelp samp img { + vertical-align: text-top; +} + +.pun .postmsg .postimg img { + max-width: 98%; + vertical-align: middle; +} + +.pun .postmsg .postimg a:link img, .pun .postmsg .postimg a:visited img { + border-style: solid; + border-width: 2px; +} + +/***************************************************************** +MAIN FORMS +*****************************************************************/ + +#punedit .blockform h2, #punpost .blockform h2, #postpreview h2, #posterror h2, +.pun #quickpost h2, .pun #reportform h2, #pundelete .blockform h2 { + font: 1em/1.462em Arial, Helvetica, sans-serif; + font-weight: bold; + white-space: nowrap; + padding: 10px 19px 4px 37px; + border: 0; +} + +#punpost .blockform h2, #punedit .blockform h2,.pun #quickpost h2, +#pundelete .blockform h2 { + margin: 1px 1px 0 1px; + width: 25em; + position: absolute; + z-index: 100; +} + +.pun #quickpost legend, #punpost legend, #punedit legend { + width: 25em; + overflow: hidden; + white-space: nowrap; +} + +.pun .blockform .box { + border-style: solid; + border-width: 1px; + padding-bottom: 12px; +} + +.pun #posterror { + border-style: solid; + border-width: 1px; +} + +.pun #posterror .box { + padding: 0 18px 12px 18px; +} + +* html .pun .blockform .box, * html .pun #posterror { + display: inline-block; +} + +.pun .blockform .forminfo, .pun .error-info { + padding: 12px 18px; + border-style: solid; + border-width: 1px; + position: relative; +} + +.pun .blockform .forminfo { + margin-top: 12px; +} + +#pundelete .blockform .forminfo { + margin-top: 33px; +} + +.pun .forminfo h3 { + padding-bottom: 0; +} + +.pun .error-list li { + padding-left: 24px; + background: url(Fire/img/exclaim.png) center left no-repeat; +} + +.pun .inform { + padding: 0 18px; +} + +.pun legend { + font-weight: bold; + padding: 10px 19px 4px 19px; +} + +* html .pun legend { + margin-left: -7px; +} + +*:first-child+html .pun legend { + margin-left: -7px; +} + +.pun .infldset { + border-style: solid; + border-width: 1px; + padding: 12px 18px; +} + +#punregister #rules .infldset { + padding: 5px 18px; +} + +.pun fieldset p { + padding: 0 0 7px 0; + width: 100%; +} + +.pun fieldset .usercontent p { + padding: 7px 0; +} + +.pun fieldset label { + display: block; + padding: 0 0 7px 0; +} + +.pun label em { + font-weight: normal; + font-style: normal; +} + +.pun .required strong { + background: url(Fire/img/asterisk.png) center right no-repeat; + font-weight: normal; + padding-right: 14px; + white-space: pre; + display: inline-block; + line-height: normal; +} + +.pun label input, .pun label select, .pun label textarea { + margin-top: 2px; +} + +.pun label.conl { + display: inline-block; + padding-right: 12px; +} + +.pun form .buttons { + padding: 8px 19px 8px 34px; + margin-bottom: -12px; +} + +.pun .blockform .buttons input { + margin-right: 12px; +} + +.pun .rbox { + padding: 3px 0; +} + +.pun .rbox label { + padding: 3px 0 3px 1.75em; + position: relative; + min-height: 1px; +} + +* html .pun .rbox label { + text-indent: -3px; + height: 1%; +} + +.pun .rbox input { + margin: 3px 0.75em 3px -1.75em; + float: left; + position: relative; + vertical-align: middle; + padding: 0; + height: 1em; + width: 1em; +} + +.pun input[type=text], .pun select, .pun textarea { + font-family: Verdana, Arial, Helvetica, sans-serif; +} + +.pun .txtarea textarea, .pun input.longinput { + width: 98%; +} + +.pun #quickpost .txtarea { + padding-right: 12px; + padding-left: 200px; + position: relative; +} + +.pun .blockform .bblinks { + padding-top: 0; +} + +.pun .blockform .bblinks li { + display: inline; +} + +.pun .blockform .bblinks li span { + background: url(Fire/img/help.png) center left no-repeat; + margin-right: 8px; + padding-left: 20px; + display: inline-block; +} + +.pun #quickpost .bblinks { + left: 18px; + line-height: 1.75em; + position:absolute; + top: 18px; + width: 12em; +} + +.pun #quickpost .bblinks li { + display: block; +} + +.pun #login p.clearb { + border-top-style: dotted; + border-top-width: 1px; + font-size: 0; + height: 0; + line-height: 0; + margin-top: 7px; + overflow: hidden; + padding-bottom: 3px; + padding-top: 7px; + text-indent: -9999em; + width: 100%; +} + +.pun #postreview { + padding-top: 12px; +} + +.pun #postpreview, .pun #posterror { + margin-bottom: 12px; +} + +.pun #postpreview .postright { + padding: 0; +} + +.pun #postpreview .postbody { + border-style: solid; + border-width: 1px; + float: none; + margin: 0 18px 12px 18px; + padding: 0; + padding: 4px 18px 4px 18px; + width: auto; +} + +.pun span.email { + background: url(Fire/img/email.png) left 65% no-repeat; + margin-right: 5px; + padding-left: 21px; + display: inline-block; + line-height: normal; +} + +.pun span.website { + background: url(Fire/img/ext.png) left 65% no-repeat; + padding-left: 18px; + display: inline-block; + line-height: normal; +} + +#punmisc #rules .box { + border-style: solid; + border-width: 1px; + padding: 5px 18px; +} + + +#punhelp .box { + border-style: solid; + border-width: 1px; + padding: 7px 12px; +} + +/***************************************************************** +PROFILES (+ ADMIN MENU) +*****************************************************************/ + +/* Profile / Admin +----------------------------------------------------------------*/ + +.pun .blockmenu { + width: 13em; + float: left; + padding-bottom: 12px; +} + +.pun .block2col .blockform, .pun .block2col .block { + margin-left: 15em; +} + +.pun .blockmenu .block2 { + padding-top: 19px; +} + +.pun .blockmenu ul { + border-top-style: dotted; + border-top-width: 1px; + padding: 0; +} + +.pun .blockmenu li { + border-bottom-style: dotted; + border-bottom-width: 1px; + font-weight: bold; + padding: 0; +} + +.pun .blockmenu a:link, .pun .blockmenu a:visited { + display: block; + padding: 9px 6px 3px 6px; + min-height: 1px; + text-decoration: none; +} + +* html .pun .blockmenu a:link, * html .pun .blockmenu a:visited { + height: 1%; +} + +.pun .blockmenu a:hover, .pun .blockmenu a:active, .pun .blockmenu a:focus { + text-decoration: none; +} + +#viewprofile .box { + border-style: solid; + border-width: 1px; + padding-bottom: 18px; +} + +#viewprofile dt, #adstats dt { + padding: 7px 0; + position: absolute; + width: 13em; + left: 0; +} + +#viewprofile dl { + border-style: solid none none none; + border-width: 1px; + margin: 7px 0; + padding: 0; + width: 100%; + position: relative; +} + +#adintro, #adstats { + border-style: solid; + border-width: 1px; + padding: 18px; +} + +#adstats .inbox, #adintro .inbox { + border-style: solid; + border-width: 1px; + padding: 18px; +} + +#adstats dl { + margin: 0; + padding: 0; + width: 100%; + position: relative; +} + +#viewprofile dd, #adstats dd { + border-style: none none solid none; + border-width: 1px; + padding: 7px 0 7px 13em; +} + +/***************************************************************** +COLOUR SCHEME +*****************************************************************/ + +/* Basic defaults and Common Items +----------------------------------------------------------------*/ + +html, body, .pun { + background: #eeedea; + color: #333; +} + +.pun .punwrap { + background: #fff; + border-color: #e1d9ca; + color: #665858; +} + +#brdtitle #brddesc, .pun .pagepost, #brdstats #onlinelist, #brdfooter #searchlinks, #brdfooter #modcontrols, +#punmaint h2, #punredirect h2, #adminconsole .submittop, .pun #debugtime, .pun .pagelink * { + border-color: #cec7b9; +} + +.pun a, .pun a:link, .pun a:visited { + color: #990000; +} + +.pun a:hover, .pun a:active, .pun a:focus { + color: #f60; +} + +.pun .postmsg .postimg a:link img, .pun .postmsg .postimg a:visited img { + border-color: #990000; +} + +.pun .postmsg .postimg a:hover img, .pun .postmsg .postimg a:active img, .pun .postmsg .postimg a:focus img { + border-color: #f60; +} + +/* Primary Navigation +----------------------------------------------------------------*/ + +#brdmenu { + background: #990000; +} + +#brdmenu a, #brdmenu a:link, #brdmenu a:visited { + background: #990000; + border-color: #fff; + color: #ddd; +} + +#brdmenu a:hover, #brdmenu a:active, #brdmenu a:focus { + background: #f60; + border-color: #fff; + color: #fff; +} + +/* Main Tables +----------------------------------------------------------------*/ + +.pun .blocktable .box { + background: #fbfaf5; + border-color: #cec7b9 #e7e2d9; +} + +#punindex .blocktable h2, .pun #vf h2 { + color: #836359; +} + +#adminconsole fieldset th, #adminconsole fieldset td { + background: #f3f2ed; + border-color: #ebe0dc; +} + +.pun #users1 h2 { + background: #fff; +} + +.pun .blocktable td { + border-color: #ebe0dc; +} + +.pun .blocktable th { + background: #ecebe7; + border-color: #e1d9ca; + color: #836359; +} + +.pun .blocktable td.tcl span.stickytext { + color: #000; +} + +/* Main Posts +----------------------------------------------------------------*/ + +.pun .blockpost { + background: #f3f2ed; + border-color: #cec7b9 #e7e2d9; +} + +.pun .blockpost h2 { + background: #ecebe7; + border-color: #e1d9ca; + color: #836359; +} + +.pun .blockpost .postbody, .pun .blockpost .postfoot { + background: #fbfaf5; + border-color: #ebe0dc; +} + +.pun .blockpost .postfootright li { + color: #fbfaf5; +} + +.pun .postmsg, #punhelp code, #punhelp samp { + color: #333; +} + +.pun .postsignature, .pun .postmsg .postedit { + color: #665858; +} + +.pun .quotebox { + background: #f4f4e8; + border-color: #ccc; + color: #665858; +} + +.pun .quotebox cite { + color: #836359; +} + +.pun .codebox, #punhelp .codebox code { + background: #333; + color: #fff; +} + +.pun .postmsg hr { + background: #cec7b9; +} + +.pun .postmsg ins, #punhelp samp ins { + background-color: #ff0; +} + +/* Main Forms + Profile +----------------------------------------------------------------*/ + +.pun .blockform .box, #adstats, #adintro, #postpreview, #posterror { + border-color: #cec7b9 #e7e2d9; + background: #ecebe7; +} + +#punmisc #rules .box, #punhelp .box { + border-color: #cec7b9 #e7e2d9; + background: #f3f2ed; +} + +.pun #quickpost h2, #punpost .blockform h2, #punedit .blockform h2, #posterror h2, +#pundelete .blockform h2 { + background: #ecebe7; + color: #836359; +} + +.pun .forminfo { + background: #fff; + border-color: #ebe0dc; +} + +#puninstall form#install .forminfo { + background: #990000; + color: #fff; +} + +.pun #posterror .error-info { + background: #ffffe1; + border-color: #dfe6ee; +} + +#puninstall form#install .error-info { + background: #ffffe1; + border-color: #dfe6ee; + color: #333; +} + +.pun .infldset, #adintro .inbox, #adstats .inbox { + background: #f3f2ed; + border-color: #ebe0dc; +} + +.pun label, .pun legend, #adminconsole fieldset th { + color: #836359; +} + +.pun fieldset p { + border-color: #cec7b9; +} + +.pun .blockmenu ul, .pun .blockmenu li { + border-color: #cec7b9; +} + +.pun .blockmenu a:hover, .pun .blockmenu a:active, .pun .blockmenu a:focus { + background: #ffffe6; +} + +.pun .blockmenu .isactive a:link, .pun .blockmenu .isactive a:visited { + color: #333; + background: #f3f2ed; + } + +.pun #viewprofile .box { + border-color: #cec7b9 #e7e2d9; + background: #ecebe7; +} + +.pun #viewprofile dt, #adstats dt { + color: #836359; +} + +.pun #viewprofile dl, .pun #viewprofile dd, #adstats dl, #adstats dd { + border-color: #ebe0dc; +} + +#adminconsole fieldset td.nodefault { + background: #d59b9b; +} + +/* Status Indicators +----------------------------------------------------------------*/ + +.pun .icon { + border-color: #f1eee8 #dddad4 #e8e5df #f1efe8; +} + +.pun .iredirect .icon { + border-color: #cec7b9; + border-width: 1px; + padding: 7px; +} + +.pun .inew .icon { + border-color: #ca0000 #ab0000 #bb0000 #d30000; +} diff --git a/style/Fire/base_admin.css b/style/Fire/base_admin.css new file mode 100644 index 0000000..66bfe2c --- /dev/null +++ b/style/Fire/base_admin.css @@ -0,0 +1,144 @@ +#adminconsole .blockform .box { + padding-bottom: 12px; +} + +#adminconsole fieldset .infldset { + position: relative; + overflow: hidden; +} + +#adminconsole fieldset table { + margin-top: -1px; + margin-bottom: -1px; +} + +#adminconsole fieldset td, #adminconsole fieldset th { + padding: 10px 8px 10px 0; + text-align: left; + white-space: normal; + border-style: solid none; + border-width: 1px 0; +} + +#punadmin thead th { + border-top: 0; + font-weight: normal; +} + +#adminconsole fieldset td span, #adminconsole fieldset th span { + display: block; font-size: 1em; + font-weight: normal; +} + +#adminconsole fieldset td.location span { + display: inline-block; +} + +#adminconsole fieldset tbody th { + width: 15em; + font-weight: normal; + padding-right: 8px; +} + +#adminconsole table.aligntop th, #adminconsole table.aligntop td { + vertical-align: top; +} + +#adminconsole table.aligntop th div { + padding-top: 3px; +} + +#adminconsole .inform { + padding-bottom: 0; +} + +#adminconsole .infldset { + padding-bottom: 0; + padding-top: 0; +} + +#adminconsole p.submittop { + text-align: center; + border-bottom-style: dotted; + border-bottom-width: 1px; + margin: 0 18px; + padding-top: 12px; +} + +#adminconsole p.submitend { + text-align: center; + padding-bottom: 0; +} + +#adminconsole fieldset p { + padding: 10px 0; +} + +#adminconsole .fsetsubmit { + padding: 10px 0 12px 0; +} + +#categoryedit .tcl { + width: 25%; +} + +#censoring .tcl, #censoring .tc2, #ranks .tcl, #ranks .tc2 { + width: 20%; +} + +#edforum .tcl { + width: 18%; +} + +#edforum .tc2 { + width: 12%; +} + +#forumperms thead th, #forumperms tbody td { + text-align: center; +} + +.pun .linkst .backlink, .pun .linksb .backlink { + padding: 7px 0; +} + +#punadmin #users1 h2, #punadmin #users2 h2, #punadmin #bans1 h2 { + display: block; + left: -9999em; + overflow: hidden; + position: absolute; + text-indent: -9999em; + width: 0; +} + +#punadmin #users1 th, #punadmin #users2 th, #punadmin #bans1 th { + font-weight: bold; + } + +#users2 th, #bans1 th { + text-align: left; +} + +#users2 .tcl, #users2 .tc3, #users2 .tc5, #bans1 .tcl, #bans1 .tc3, #bans1 .tc5, #bans1 .tc6 { + width: 15%; + text-align: left; +} + +#users2 .tc2, #bans1 .tc2 { + width: 22%; + text-align: left; +} + +#users2 .tc4, #bans1 .tc4 { + width: 8%; + text-align: center; +} + +#users2 .tcr, #bans1 .tcr { + white-space: nowrap; +} + +#exampleplugin p { + padding-left: 18px; + padding-right: 18px; +} \ No newline at end of file diff --git a/style/Fire/img/asterisk.png b/style/Fire/img/asterisk.png new file mode 100644 index 0000000..d00ef54 Binary files /dev/null and b/style/Fire/img/asterisk.png differ diff --git a/style/Fire/img/bull.png b/style/Fire/img/bull.png new file mode 100644 index 0000000..3fd1f61 Binary files /dev/null and b/style/Fire/img/bull.png differ diff --git a/style/Fire/img/email.png b/style/Fire/img/email.png new file mode 100644 index 0000000..bdd5ff8 Binary files /dev/null and b/style/Fire/img/email.png differ diff --git a/style/Fire/img/exclaim.png b/style/Fire/img/exclaim.png new file mode 100644 index 0000000..92eb57b Binary files /dev/null and b/style/Fire/img/exclaim.png differ diff --git a/style/Fire/img/ext.png b/style/Fire/img/ext.png new file mode 100644 index 0000000..30a27ec Binary files /dev/null and b/style/Fire/img/ext.png differ diff --git a/style/Fire/img/feed.png b/style/Fire/img/feed.png new file mode 100644 index 0000000..d4cf8ce Binary files /dev/null and b/style/Fire/img/feed.png differ diff --git a/style/Fire/img/help.png b/style/Fire/img/help.png new file mode 100644 index 0000000..a8a7367 Binary files /dev/null and b/style/Fire/img/help.png differ diff --git a/style/Fire/img/index.html b/style/Fire/img/index.html new file mode 100644 index 0000000..89337b2 --- /dev/null +++ b/style/Fire/img/index.html @@ -0,0 +1 @@ +.. diff --git a/style/Fire/img/main_end.png b/style/Fire/img/main_end.png new file mode 100644 index 0000000..15a5937 Binary files /dev/null and b/style/Fire/img/main_end.png differ diff --git a/style/Fire/img/main_top.png b/style/Fire/img/main_top.png new file mode 100644 index 0000000..e951ebd Binary files /dev/null and b/style/Fire/img/main_top.png differ diff --git a/style/Fire/index.html b/style/Fire/index.html new file mode 100644 index 0000000..89337b2 --- /dev/null +++ b/style/Fire/index.html @@ -0,0 +1 @@ +.. diff --git a/style/Lithium.css b/style/Lithium.css new file mode 100644 index 0000000..96f75a0 --- /dev/null +++ b/style/Lithium.css @@ -0,0 +1,1085 @@ +/***************************************************************** +1. INITIAL SETTINGS +*****************************************************************/ + +/* Limited Reset +----------------------------------------------------------------*/ + +.pun table, .pun div, .pun form, .pun p, .pun h1, .pun h2, .pun h3, +.pun h4, .pun h5, .pun pre, .pun blockquote, .pun ul, .pun ol, .pun li, .pun dl, +.pun dt, .pun dd, .pun th, .pun td, .pun fieldset, .pun img, .pun abbr, .pun cite { + margin: 0; + padding: 0; + border: 0; + } + +.pun ul, .pun ol { + list-style: none + } + + +/* Structural Settings +----------------------------------------------------------------*/ + +.pun .clearer, .pun .nosize { + height: 0; + width: 0; + line-height: 0; + font-size: 0; + overflow: hidden + } + +.pun .clearer, .pun .clearb { + clear: both + } + +.pun .nosize { + position: absolute; + left: -9999em; + text-indent: -9999em; + width: 0; + } + +* html .inbox, * html .inform, * html .pun, * html .tclcon, * html .codebox { + height: 1px + } + +.pun, .pun .inbox, .pun .inform, .pun .tclcon, .pun .codebox { + min-height: 1px + } + + +/* Hidden Elements +----------------------------------------------------------------*/ + +#brdfooter h2, #brdstats h2, #brdstats .conl dt, #brdstats .conr dt, +#modcontrols dt, #searchlinks dt, div.postright h3, span.closedtext, +.pun .required strong span { + position: absolute; + display: block; + overflow: hidden; + width: 0; + left: -9999em; + text-indent: -9999em; + } + +/***************************************************************** +2. TEXT & CONTENT +*****************************************************************/ + +/* Text Defaults +----------------------------------------------------------------*/ + +.pun { + font: 68.75%/1.4545em Verdana, Helvetica, Arial, sans-serif; + } + +.pun table, .pun td, .pun th, .pun input, .pun select, .pun optgroup, .pun textarea, .pun samp { + font-size: 1em; + font-family: verdana, helvetica, arial, sans-serif; + } + +.pun pre, .pun code { + font-size: 1.182em; + font-family: consolas, monaco, "bitstream vera sans mono", "courier new", courier, monospace + } + +.pun pre code { + font-size: 1em; + } + +.pun strong { + font-weight: bold; + } + +.pun em { + font-style: italic; + } + + +/* Content Defaults +----------------------------------------------------------------*/ + +.pun p, .pun ul, .pun ol, .pun dl { + font-size: 1em; + padding: 3px 0; + } + +.pun h2 { + font-size: 1em; + font-weight: normal; + padding: 4px 7px; + } + +.pun h3 { + font-size: 1.091em; + padding: 3px 0; + } + +.pun table p, .pun table h3 { + padding: 0; + } + +.pun span.warntext, .pun p.warntext { + font-weight: bold + } + +/* User Content (Announcements, Rules, Posts) +----------------------------------------------------------------*/ + +.pun .usercontent p, .pun .postmsg p { + padding: 0.75em 0 + } + +.pun .usercontent ul, .pun .postmsg ul { + padding: 0.75em 1em 0.75em 2.5em; + list-style: disc + } + +.pun .usercontent ol, .pun .postmsg ol { + padding: 0.75em 1em 0.75em 2.5em; + list-style: decimal + } + +.pun .usercontent ol.alpha, .pun .postmsg ol.alpha { + list-style: lower-alpha + } + +.pun .usercontent li ol, .pun .usercontent li ul, .pun .postmsg li ol, .pun .postmsg li ul { + padding: 0.25em 1em 0.75em 2.5em + } + +.pun .usercontent li p, .pun .postmsg li p { + padding: 0 + } + +.pun .usercontent h1 { + font-size: 1.4em; + font-weight: bold; + padding: 0.75em 0 0 0 + } + +.pun .usercontent h2 { + font-size: 1.2em; + font-weight: bold; + padding: 0.75em 0 0 0 + } + +.pun .usercontent h3 { + font-size: 1.1em; + font-weight: bold; + padding: 0.75em 0 0 0 + } + +.pun .usercontent h4, .pun .usercontent h5, .pun .usercontent h6 { + font-size: 1em; + font-weight: bold; + padding: 0.75em 0 0 0 + } + +.pun .quotebox cite { + font-weight: bold; + font-style: normal; + padding: 0.75em 0.75em 0 0.75em + } + +.pun span.bbu { + text-decoration: underline + } + +.pun span.bbs, .pun del { + text-decoration: line-through; + } + +.pun .postmsg ins, #punhelp samp ins { + text-decoration: none; + } + +.pun div.postmsg h5, #punhelp h5 { + font-size: 1.1em; + font-weight: bold; + padding: 0.75em 0 0 0; + } + + +/***************************************************************** +3. COMMON STYLES +*****************************************************************/ + +/* Page Layout +----------------------------------------------------------------*/ + +.pun { + margin: 12px 20px + } + +#punredirect, #punmaint, #puninstall, #pundb_update { + margin: 50px 20% 12px 20% + } + + +/* Vertical Element Spacing +----------------------------------------------------------------*/ + +#brdheader { + margin: 0 0 12px 0; + } + +#announce, #brdstats { + margin: 12px 0 12px 0; + } + +.pun .blocktable, .pun .block, .pun .blockform, .pun .block2col, #postreview { + margin-bottom: 12px + } + +#punindex .blocktable, .pun .blockpost { + margin-bottom: 6px + } + +#postreview .blockpost { + margin-bottom: -1px; + } + +.pun .block2col .blockform, .pun .block2col .block { + margin-bottom: 0px + } + +.pun .linkst, .pun .linksb { + margin-top: -12px + } + +.pun .postlinksb { + margin-top: -6px + } + + +/* External Borders +----------------------------------------------------------------*/ + +.pun .box { + border-style: solid; + border-width: 1px; + } + +#brdheader .box { + border-top-width: 4px; + } + +/* Default Internal Spacing +----------------------------------------------------------------*/ + +.pun .block .inbox, .pun .blockmenu .inbox { + padding: 3px 6px + } + +/***************************************************************** +4. COMMON BOARD ELEMENTS +*****************************************************************/ + +/* Board Header +----------------------------------------------------------------*/ + +#brdtitle h1 { + font-size: 1.454em; + font-weight: bold; + line-height: 1em; + padding: 3px 0 0 0; + } + +#brddesc { + padding: 3px 0; + } + +#brddesc * { + padding-top: 0; + padding-bottom: 0; + } + +#brdmenu li { + display: inline; + margin-right: 12px; + } + +#brdmenu a:link, #brdmenu a:visited { + text-decoration: none + } + +#brdmenu a:hover, #brdmenu a:active { + text-decoration: underline + } + +#brdwelcome .conl { + float: left; + } + +#brdwelcome .conr { + float: right; + text-align: right; + } + +/* Breadcrumbs and Post Links +----------------------------------------------------------------*/ + +.pun .linkst { + padding: 8px 6px 3px 6px + } + +.pun .linksb, .pun .postlinksb { + padding: 3px 6px 8px 6px + } + +.pun .crumbs { + clear: both; + width: 100%; + overflow: hidden; + } + +.pun .crumbs li { + display: inline; + white-space: nowrap; + font-weight: bold; + } + +.pun .pagelink { + float: left; + white-space: nowrap; + } + +.pun .postlink { + font-weight: bold; + white-space: nowrap; + } + +.pun .postlink, .pun .modbuttons { + float: right; + text-align: right; + } + +.pun .modbuttons { + padding: 1px 0; + white-space: nowrap; + } + +.pun .modbuttons input { + margin-left: 6px; + } + +.pun .postlink a:link, .pun .postlink a:visited { + text-decoration: none + } + +.pun .postlink a:hover, .pun .postlink a:active { + text-decoration: underline; + } + + +/* Board Footer +----------------------------------------------------------------*/ + +#brdfooter .conl { + float: left; + } + +#brdfooter .conr { + float: right; + text-align: right; + } + +#brdfooter #modcontrols { + border-bottom-style: solid; + border-bottom-width: 1px; + text-align: center; + } + +#brdfooter #modcontrols dd { + display: inline; + margin:0 6px; + } + + +/* Board Stats +----------------------------------------------------------------*/ + +#brdstats .conl { + float: left; + } + +#brdstats .conr { + float: right; + text-align: right; + } + +#onlinelist dd, #onlinelist dt { + display: inline; + } + + +/***************************************************************** +5. MAIN TABLES +*****************************************************************/ + +.pun table { + width: 100%; + border-collapse: collapse; + border-spacing: 0; + empty-cells: show; + } + +.pun .blocktable table { + table-layout: fixed; + } + +.pun td, .pun th { + padding: 4px 6px; + line-height: 1.273em; + text-align: left; + font-weight: normal; + } + +.pun td { + border-style: solid none none solid; + border-width: 1px; + } + +.pun .tcl { + border-left: 0; + width: auto; + } + +.pun .tc2, .pun .tc3, .pun .tcmod { + width: 10%; + text-align: center; + padding: 4px 0; + } + +.pun .tcr { + width: 30%; + } + +.pun .tcl h3 { + font-size: 1.091em; + font-weight: bold; + } + +.pun .tcl h3 span.newtext { + font-size: 0.917em; + } + +.pun .tcl span.newtext, .pun .tcl span.pagestext { + white-space: nowrap; + font-weight: normal; + } + +.pun td span.byuser { + white-space: nowrap; + } + +.pun .tcl p { + padding: 5px 0 0 0 + } + +#punsearch #vf .tc2 { + width: 18%; + text-align: left; + padding: 4px 6px; + } + +#users1 .tcr { + width: 25% + } + +#users1 .tc2 { + width: 25%; + text-align: left; + padding: 4px 6px; + } + +#debug .tcl { + width: 10% + } + +#debug .tcr { + width: 90%; + white-space: normal + } + +#punindex .tcr .byuser { + display: block + } + +.pun .blocktable .tclcon { + padding: 0 11px 0 12px; + overflow: hidden; + height: 1%; + min-height: 1px; + position: relative; + } + +.pun .blocktable .tclcon div { + width: 100%; + overflow: hidden; + } + +.pun .icon { + border-width: 7px; + border-style: solid; + height: 0; + width: 0; + overflow: hidden; + float: left; + } + +.pun .icon div { + position: absolute; + left: -9999em; + text-indent: -9999em; + height: 0; + } + +.pun .iposted .ipost { + position: absolute; + left: 0; + font-weight: bold; + width: 8px; + padding-left: 4px; + text-align: center; + top: 0; + } + +/***************************************************************** +6. MAIN FORMS +*****************************************************************/ + +.pun .blockform form, .pun .fakeform { + PADDING: 20px 20px 15px 20px + } + +.pun .forminfo { + margin-bottom: 12px; + padding: 9px 10px; + border-style: solid; + border-width: 1px; + } + +.pun .forminfo h3 { + font-weight: bold; + } + +.pun .inform { + padding-bottom: 12px + } + +.pun fieldset { + padding: 0px 12px 0px 12px; + border-style: solid; + border-width: 1px + } + +.pun legend { + padding: 0px 6px + } + +.pun .infldset { + padding: 9px 0px 12px 0 + } + +.pun label { + display: block; + padding: 3px 0 + } + +.pun label.conl { + float: left; + overflow: visible; + margin-right: 10px + } + +.pun select { + padding-top: 1px; + padding-bottom: 1px; + } + +.pun fieldset .rbox { + } + +.pun fieldset .rbox br { + display: none; + } + +.pun fieldset .rbox label { + padding: 3px 0 3px 25px; + position: relative; + vertical-align: middle; + } + +.pun fieldset .rbox input { + margin: 0 9px 0 -25px; + padding: 0; + width: 16px; + position: relative; + vertical-align: middle; + } + +.pun .txtarea { + width: 75% + } + +.pun .txtarea textarea, .pun input.longinput { + width: 100% + } + +.pun .bblinks { + padding-bottom: 10px; + padding-left: 4px + } + +.pun .bblinks li { + display: inline; + padding-right: 20px + } + +.pun .blockform .buttons { + padding-left: 12px; + } + +.pun .blockform .buttons input { + margin-right: 8px; + } + +#posterror ul { + list-style: square; + padding: 3px 0 3px 24px; + } + +.pun .deletemsg { + border-style: solid; + border-width: 1px; + padding: 6px 15px; + } + +.pun p.actions span { + margin-right: 12px; + } + +/***************************************************************** +7. PROFILES AND ADMIN +*****************************************************************/ + +.pun .block2col { + padding-bottom: 1px + } + +.pun .block2col .blockform, .pun .block2col .block { + margin-left: 17em + } + +.pun .blockmenu { + float:left; + width: 16em + } + +.pun .blockmenu li { + padding: 3px 0; + font-weight: bold; + } + +.pun .blockmenu a:link, .pun .blockmenu a:visited { + text-decoration: none + } + +.pun .blockmenu a:hover, .pun .blockmenu a:active { + text-decoration: underline + } + +#viewprofile dl { + float: left; + width: 100%; + overflow: hidden + } + +#viewprofile dd { + margin-left: 14em; + padding: 3px; + } + +#viewprofile dt { + float: left; + width: 13em; + margin: 3px 0; + } + +#profileavatar img { + float: right; + margin-left: 1em + } + +/***************************************************************** +8. MAIN POSTS +*****************************************************************/ + +.pun .blockpost h2 a:link, .pun .blockpost h2 a:visited { + text-decoration: none; + } + +.pun .blockpost h2 a:hover, .pun .blockpost h2 a:active { + text-decoration: underline; + } + +.pun .blockpost h2 .conr { + float: right; + text-align: right; + } + +#punsearch .blockpost h2 span { + white-space: nowrap; + } + +.pun .blockpost .box { + overflow: hidden; + } + +.pun .postleft, .pun .postfootleft { + float:left; + width: 18em; + position: relative; + overflow: hidden; + } + +.pun .postleft dl { + padding: 0.75em 6px; + } + +.pun .postleft .usercontacts, .pun .postleft .icon { + margin-top: 6px + } + +.pun .postleft .postavatar, .pun .postleft .usertitle { + margin-bottom: 6px; + display: block; + } + +.pun .blockpost dt { + font-size: 1.091em; + font-weight: bold; + } + +.pun .blockpost dt a:link, .pun .blockpost dt a:visited { + text-decoration: none; + } + +.pun .blockpost dt a:hover, .pun .blockpost dt a:active { + text-decoration: underline; + } + +.pun .postright, .pun .postfootright { + border-left-width: 18em; + border-left-style: solid + } + +#postpreview .postright { + border-left: 0 + } + +.pun .postright { + padding: 0 6px; + } + +.pun .postfootright, .pun .multidelete { + text-align: right + } + +.pun .postmsg { + width:98%; + overflow: hidden; + padding-bottom: 6px; + } + +.pun .postfootright ul, .pun .postfootright div, .pun .postfootright p, +.pun .postfootleft p { + padding: 6px 6px 6px 6px; + } + +.pun .postfootright li { + display: inline; + margin-left: 12px; + } + +.pun .postfootright a:link, .pun .postfootright a:visited { + text-decoration: none + } + +.pun .postfootright a:hover, .pun .postfootright a:active { + text-decoration: underline + } + +.pun .codebox { + border-style: solid; + border-width: 1px; + margin: 0.75em 1em; + padding: 0; + } + +.pun .quotebox { + border-style: solid; + border-width: 1px; + margin: 0.75em 1em; + padding: 0 0.75em; + } + +.pun .quotebox cite { + display: block; + padding: 0.75em 0 0 0; + } + +.pun .quotebox blockquote { + width: 100%; + overflow: hidden + } + +.pun .codebox pre { + overflow: auto; + width: 100%; + overflow-y:hidden + } + +* html .pun .codebox pre { + padding-bottom: 10px; + } + +*+html .pun .codebox pre { + padding-bottom: 10px + } + +.pun .codebox pre code { + display: block; + padding: 0.75em; + } + +.pun .codebox pre.vscroll { + height: 32em; + overflow: auto; + overflow-y: auto + } + +.pun .postmsg img { + vertical-align: bottom; + } + +.pun .postsignature hr { + margin-left: 0px; + width: 200px; + text-align: left; + height: 1px; + border:none + } + +.pun .postmsg .postimg img { + max-width: 98%; + vertical-align: middle; +} + +.pun .postmsg .postimg a:link img, .pun .postmsg .postimg a:visited img { + border-style: solid; + border-width: 2px; +} + +.pun .blockpost label { + padding: 3px 6px; + border-style: solid; + border-width: 1px; + vertical-align: middle; + display: inline-block; + } + +.pun .blockpost label * { + vertical-align: middle; + margin: 0; + padding: 0; + } + +/****************************************************************/ +/* 9. HELP FILES AND MISC. */ +/****************************************************************/ + +#punhelp h2 { + margin-top: 12px + } + +#punhelp div.box { + padding: 10px + } + +#debugtime { + margin-top: -12px; + text-align: center; + } + +/***************************************************************** +COLOUR SCHEME +*****************************************************************/ + +/* Background / Text +----------------------------------------------------------------*/ + +body { + background: #fff; + color: #333 + } + +.pun { + color: #333 + } + +.pun .box, #adminconsole fieldset th { + background-color: #f1f1f1 + } + +.pun td.tc2, .pun td.tc3, .pun td.tcmod, #postpreview, #viewprofile dd, .pun .forminfo, +#brdfooter #modcontrols, #adminconsole fieldset td, .pun .blockmenu .box, #adstats dd { + background-color: #dedfdf + } + +.pun h2, #brdmenu { + background-color: #6c8a3f; + color: #fff + } + +.pun th { + background-color: #d1d1d1 + } + +.pun legend { + color: #6c8a3f + } + +.pun .blockmenu li.isactive a, #posterror li strong { + color: #333 + } + +.pun .usercontent * { + background: transparent; + color: #333 + } + +/* posts +----------------------------------------------------------------*/ + +.pun .blockpost .box, .pun .postright, .pun .postfootright, .pun .deletemsg { + background-color: #dedfdf + } + +.pun .postright, .pun .postfootright { + border-left-color: #f1f1f1 + } + +.pun .postleft, .pun .postfootleft, .pun .blockpost label, .pun .codebox, .pun .quotebox { + background-color: #f1f1f1 + } + +#punhelp .codebox, #punhelp .quotebox { + background-color: #f9f9f9; + } + +.pun .blockpost h2 { + background-color: #7ea34b + } + +.pun .blockpost h2 span.conr { + color: #b7d094 + } + +.pun .postmsg ins, #punhelp samp ins { + background-color: #ff0; + } + +.pun hr { + background-color: #333; + color: #333 + } + +/* Borders +----------------------------------------------------------------*/ + +.pun .box { + border-color: #6c8a3f + } + +.pun td, #brdfooter #modcontrols { + border-color: #cedeb9 + } + +.pun th, .pun fieldset { + border-color: #d1d1d1 + } + +#adminconsole td, #adminconsole th { + border-color: #f1f1f1 + } + +.pun .quotebox, .pun .codebox, .pun .forminfo, +.pun .blockpost label, .pun .deletemsg { + border-color: #aca899 #fff #fff #aca899 + } + +/* Links +----------------------------------------------------------------*/ + +.pun a:link, .pun a:visited { + color: #638137 + } + +.pun a:hover, .pun a:active, .pun a:focus { + color: #8eb653 + } + +.pun .postmsg .postimg a:link img, .pun .postmsg .postimg a:visited img { + border-color: #638137; +} + +.pun .postmsg .postimg a:hover img, .pun .postmsg .postimg a:active img, .pun .postmsg .postimg a:focus img { + border-color: #8eb653; +} + +.pun h2 a:link, .pun h2 a:visited, +#brdmenu a:link, #brdmenu a:visited { + color: #fff + } + +.pun h2 a:hover, .pun h2 a:active, +#brdmenu a:hover, #brdmenu a:active { + color: #fff + } + +.pun .postreport a:link, .pun .postreport a:visited, +.pun .iclosed td.tcl a:link, .pun .iclosed td.tcl a:visited { + color: #888 + } + +.pun .postreport a:hover, .pun .postreport a:active, +.pun .iclosed td.tcl a:hover, .pun .iclosed td.tcl a:active { + color: #aaa + } + +.pun .maintenancelink a:link, .pun .maintenancelink a:visited { + color: #b42000 + } + +.pun .maintenancelink a:hover, .pun .maintenancelink a:active { + color: #b42000 + } + +/* Status Indicators +----------------------------------------------------------------*/ + +.pun .icon { + border-color: #e6e6e6 #dedede #dadada #e2e2e2 + } + +.pun .iredirect .icon { + border-color: #f1f1f1 #f1f1f1 #f1f1f1 #f1f1f1 + } + +.pun .inew .icon { + border-color: #8bb453 #7a9e48 #709142 #799c47 + } diff --git a/style/Mercury.css b/style/Mercury.css new file mode 100644 index 0000000..708bde6 --- /dev/null +++ b/style/Mercury.css @@ -0,0 +1,1086 @@ +/***************************************************************** +1. INITIAL SETTINGS +*****************************************************************/ + +/* Limited Reset +----------------------------------------------------------------*/ + +.pun table, .pun div, .pun form, .pun p, .pun h1, .pun h2, .pun h3, +.pun h4, .pun h5, .pun pre, .pun blockquote, .pun ul, .pun ol, .pun li, .pun dl, +.pun dt, .pun dd, .pun th, .pun td, .pun fieldset, .pun img, .pun abbr, .pun cite { + margin: 0; + padding: 0; + border: 0; + } + +.pun ul, .pun ol { + list-style: none + } + + +/* Structural Settings +----------------------------------------------------------------*/ + +.pun .clearer, .pun .nosize { + height: 0; + width: 0; + line-height: 0; + font-size: 0; + overflow: hidden + } + +.pun .clearer, .pun .clearb { + clear: both + } + +.pun .nosize { + position: absolute; + left: -9999em; + text-indent: -9999em; + width: 0; + } + +* html .inbox, * html .inform, * html .pun, * html .tclcon, * html .codebox { + height: 1px + } + +.pun, .pun .inbox, .pun .inform, .pun .tclcon, .pun .codebox { + min-height: 1px + } + + +/* Hidden Elements +----------------------------------------------------------------*/ + +#brdfooter h2, #brdstats h2, #brdstats .conl dt, #brdstats .conr dt, +#modcontrols dt, #searchlinks dt, div.postright h3, span.closedtext, +.pun .required strong span { + position: absolute; + display: block; + overflow: hidden; + width: 0; + left: -9999em; + text-indent: -9999em; + } + +/***************************************************************** +2. TEXT & CONTENT +*****************************************************************/ + +/* Text Defaults +----------------------------------------------------------------*/ + +.pun { + font: 68.75%/1.4545em Verdana, Helvetica, Arial, sans-serif; + } + +.pun table, .pun td, .pun th, .pun input, .pun select, .pun optgroup, .pun textarea, .pun samp { + font-size: 1em; + font-family: verdana, helvetica, arial, sans-serif; + } + +.pun pre, .pun code { + font-size: 1.182em; + font-family: consolas, monaco, "bitstream vera sans mono", "courier new", courier, monospace + } + +.pun pre code { + font-size: 1em; + } + +.pun strong { + font-weight: bold; + } + +.pun em { + font-style: italic; + } + + +/* Content Defaults +----------------------------------------------------------------*/ + +.pun p, .pun ul, .pun ol, .pun dl { + font-size: 1em; + padding: 3px 0; + } + +.pun h2 { + font-size: 1em; + font-weight: normal; + padding: 4px 7px; + } + +.pun h3 { + font-size: 1.091em; + padding: 3px 0; + } + +.pun table p, .pun table h3 { + padding: 0; + } + +.pun span.warntext, .pun p.warntext { + font-weight: bold + } + +/* User Content (Announcements, Rules, Posts) +----------------------------------------------------------------*/ + +.pun .usercontent p, .pun .postmsg p { + padding: 0.75em 0 + } + +.pun .usercontent ul, .pun .postmsg ul { + padding: 0.75em 1em 0.75em 2.5em; + list-style: disc + } + +.pun .usercontent ol, .pun .postmsg ol { + padding: 0.75em 1em 0.75em 2.5em; + list-style: decimal + } + +.pun .usercontent ol.alpha, .pun .postmsg ol.alpha { + list-style: lower-alpha + } + +.pun .usercontent li ol, .pun .usercontent li ul, .pun .postmsg li ol, .pun .postmsg li ul { + padding: 0.25em 1em 0.75em 2.5em + } + +.pun .usercontent li p, .pun .postmsg li p { + padding: 0 + } + +.pun .usercontent h1 { + font-size: 1.4em; + font-weight: bold; + padding: 0.75em 0 0 0 + } + +.pun .usercontent h2 { + font-size: 1.2em; + font-weight: bold; + padding: 0.75em 0 0 0 + } + +.pun .usercontent h3 { + font-size: 1.1em; + font-weight: bold; + padding: 0.75em 0 0 0 + } + +.pun .usercontent h4, .pun .usercontent h5, .pun .usercontent h6 { + font-size: 1em; + font-weight: bold; + padding: 0.75em 0 0 0 + } + +.pun .quotebox cite { + font-weight: bold; + font-style: normal; + padding: 0.75em 0.75em 0 0.75em + } + +.pun span.bbu { + text-decoration: underline + } + +.pun span.bbs, .pun del { + text-decoration: line-through; + } + +.pun .postmsg ins, #punhelp samp ins { + text-decoration: none; + } + +.pun div.postmsg h5, #punhelp h5 { + font-size: 1.1em; + font-weight: bold; + padding: 0.75em 0 0 0; + } + + +/***************************************************************** +3. COMMON STYLES +*****************************************************************/ + +/* Page Layout +----------------------------------------------------------------*/ + +.pun { + margin: 12px 20px + } + +#punredirect, #punmaint, #puninstall, #pundb_update { + margin: 50px 20% 12px 20% + } + + +/* Vertical Element Spacing +----------------------------------------------------------------*/ + +#brdheader { + margin: 0 0 12px 0; + } + +#announce, #brdstats { + margin: 12px 0 12px 0; + } + +.pun .blocktable, .pun .block, .pun .blockform, .pun .block2col, #postreview { + margin-bottom: 12px + } + +#punindex .blocktable, .pun .blockpost { + margin-bottom: 6px + } + +#postreview .blockpost { + margin-bottom: -1px; + } + +.pun .block2col .blockform, .pun .block2col .block { + margin-bottom: 0px + } + +.pun .linkst, .pun .linksb { + margin-top: -12px + } + +.pun .postlinksb { + margin-top: -6px + } + + +/* External Borders +----------------------------------------------------------------*/ + +.pun .box { + border-style: solid; + border-width: 1px; + } + +#brdheader .box { + border-top-width: 4px; + } + +/* Default Internal Spacing +----------------------------------------------------------------*/ + +.pun .block .inbox, .pun .blockmenu .inbox { + padding: 3px 6px + } + +/***************************************************************** +4. COMMON BOARD ELEMENTS +*****************************************************************/ + +/* Board Header +----------------------------------------------------------------*/ + +#brdtitle h1 { + font-size: 1.454em; + font-weight: bold; + line-height: 1em; + padding: 3px 0 0 0; + } + +#brddesc { + padding: 3px 0; + } + +#brddesc * { + padding-top: 0; + padding-bottom: 0; + } + +#brdmenu li { + display: inline; + margin-right: 12px; + } + +#brdmenu a:link, #brdmenu a:visited { + text-decoration: none + } + +#brdmenu a:hover, #brdmenu a:active { + text-decoration: underline + } + +#brdwelcome .conl { + float: left; + } + +#brdwelcome .conr { + float: right; + text-align: right; + } + +/* Breadcrumbs and Post Links +----------------------------------------------------------------*/ + +.pun .linkst { + padding: 8px 6px 3px 6px + } + +.pun .linksb, .pun .postlinksb { + padding: 3px 6px 8px 6px + } + +.pun .crumbs { + clear: both; + width: 100%; + overflow: hidden; + } + +.pun .crumbs li { + display: inline; + white-space: nowrap; + font-weight: bold; + } + +.pun .pagelink { + float: left; + white-space: nowrap; + } + +.pun .postlink { + font-weight: bold; + white-space: nowrap; + } + +.pun .postlink, .pun .modbuttons { + float: right; + text-align: right; + } + +.pun .modbuttons { + padding: 1px 0; + white-space: nowrap; + } + +.pun .modbuttons input { + margin-left: 6px; + } + +.pun .postlink a:link, .pun .postlink a:visited { + text-decoration: none + } + +.pun .postlink a:hover, .pun .postlink a:active { + text-decoration: underline; + } + + +/* Board Footer +----------------------------------------------------------------*/ + +#brdfooter .conl { + float: left; + } + +#brdfooter .conr { + float: right; + text-align: right; + } + +#brdfooter #modcontrols { + border-bottom-style: solid; + border-bottom-width: 1px; + text-align: center; + } + +#brdfooter #modcontrols dd { + display: inline; + margin:0 6px; + } + + +/* Board Stats +----------------------------------------------------------------*/ + +#brdstats .conl { + float: left; + } + +#brdstats .conr { + float: right; + text-align: right; + } + +#onlinelist dd, #onlinelist dt { + display: inline; + } + + +/***************************************************************** +5. MAIN TABLES +*****************************************************************/ + +.pun table { + width: 100%; + border-collapse: collapse; + border-spacing: 0; + empty-cells: show; + } + +.pun .blocktable table { + table-layout: fixed; + } + +.pun td, .pun th { + padding: 4px 6px; + line-height: 1.273em; + text-align: left; + font-weight: normal; + } + +.pun td { + border-style: solid none none solid; + border-width: 1px; + } + +.pun .tcl { + border-left: 0; + width: auto; + } + +.pun .tc2, .pun .tc3, .pun .tcmod { + width: 10%; + text-align: center; + padding: 4px 0; + } + +.pun .tcr { + width: 30%; + } + +.pun .tcl h3 { + font-size: 1.091em; + font-weight: bold; + } + +.pun .tcl h3 span.newtext { + font-size: 0.917em; + } + +.pun .tcl span.newtext, .pun .tcl span.pagestext { + white-space: nowrap; + font-weight: normal; + } + +.pun td span.byuser { + white-space: nowrap; + } + +.pun .tcl p { + padding: 5px 0 0 0 + } + +#punsearch #vf .tc2 { + width: 18%; + text-align: left; + padding: 4px 6px; + } + +#users1 .tcr { + width: 25% + } + +#users1 .tc2 { + width: 25%; + text-align: left; + padding: 4px 6px; + } + +#debug .tcl { + width: 10% + } + +#debug .tcr { + width: 90%; + white-space: normal + } + +#punindex .tcr .byuser { + display: block + } + +.pun .blocktable .tclcon { + padding: 0 11px 0 12px; + overflow: hidden; + height: 1%; + min-height: 1px; + position: relative; + } + +.pun .blocktable .tclcon div { + width: 100%; + overflow: hidden; + } + +.pun .icon { + border-width: 7px; + border-style: solid; + height: 0; + width: 0; + overflow: hidden; + float: left; + } + +.pun .icon div { + position: absolute; + left: -9999em; + text-indent: -9999em; + height: 0; + } + +.pun .iposted .ipost { + position: absolute; + left: 0; + font-weight: bold; + width: 8px; + padding-left: 4px; + text-align: center; + top: 0; + } + +/***************************************************************** +6. MAIN FORMS +*****************************************************************/ + +.pun .blockform form, .pun .fakeform { + PADDING: 20px 20px 15px 20px + } + +.pun .forminfo { + margin-bottom: 12px; + padding: 9px 10px; + border-style: solid; + border-width: 1px; + } + +.pun .forminfo h3 { + font-weight: bold; + } + +.pun .inform { + padding-bottom: 12px + } + +.pun fieldset { + padding: 0px 12px 0px 12px; + border-style: solid; + border-width: 1px + } + +.pun legend { + padding: 0px 6px + } + +.pun .infldset { + padding: 9px 0px 12px 0 + } + +.pun label { + display: block; + padding: 3px 0 + } + +.pun label.conl { + float: left; + overflow: visible; + margin-right: 10px + } + +.pun select { + padding-top: 1px; + padding-bottom: 1px; + } + +.pun fieldset .rbox { + } + +.pun fieldset .rbox br { + display: none; + } + +.pun fieldset .rbox label { + padding: 3px 0 3px 25px; + position: relative; + vertical-align: middle; + } + +.pun fieldset .rbox input { + margin: 0 9px 0 -25px; + padding: 0; + width: 16px; + position: relative; + vertical-align: middle; + } + +.pun .txtarea { + width: 75% + } + +.pun .txtarea textarea, .pun input.longinput { + width: 100% + } + +.pun .bblinks { + padding-bottom: 10px; + padding-left: 4px + } + +.pun .bblinks li { + display: inline; + padding-right: 20px + } + +.pun .blockform .buttons { + padding-left: 12px; + } + +.pun .blockform .buttons input { + margin-right: 8px; + } + +#posterror ul { + list-style: square; + padding: 3px 0 3px 24px; + } + +.pun .deletemsg { + border-style: solid; + border-width: 1px; + padding: 6px 15px; + } + +.pun p.actions span { + margin-right: 12px; + } + +/***************************************************************** +7. PROFILES AND ADMIN +*****************************************************************/ + +.pun .block2col { + padding-bottom: 1px + } + +.pun .block2col .blockform, .pun .block2col .block { + margin-left: 17em + } + +.pun .blockmenu { + float:left; + width: 16em + } + +.pun .blockmenu li { + padding: 3px 0; + font-weight: bold; + } + +.pun .blockmenu a:link, .pun .blockmenu a:visited { + text-decoration: none + } + +.pun .blockmenu a:hover, .pun .blockmenu a:active { + text-decoration: underline + } + +#viewprofile dl { + float: left; + width: 100%; + overflow: hidden + } + +#viewprofile dd { + margin-left: 14em; + padding: 3px; + } + +#viewprofile dt { + float: left; + width: 13em; + margin: 3px 0; + } + +#profileavatar img { + float: right; + margin-left: 1em + } + +/***************************************************************** +8. MAIN POSTS +*****************************************************************/ + +.pun .blockpost h2 a:link, .pun .blockpost h2 a:visited { + text-decoration: none; + } + +.pun .blockpost h2 a:hover, .pun .blockpost h2 a:active { + text-decoration: underline; + } + +.pun .blockpost h2 .conr { + float: right; + text-align: right; + } + +#punsearch .blockpost h2 span { + white-space: nowrap; + } + +.pun .blockpost .box { + overflow: hidden; + } + +.pun .postleft, .pun .postfootleft { + float:left; + width: 18em; + position: relative; + overflow: hidden; + } + +.pun .postleft dl { + padding: 0.75em 6px; + } + +.pun .postleft .usercontacts, .pun .postleft .icon { + margin-top: 6px + } + +.pun .postleft .postavatar, .pun .postleft .usertitle { + margin-bottom: 6px; + display: block; + } + +.pun .blockpost dt { + font-size: 1.091em; + font-weight: bold; + } + +.pun .blockpost dt a:link, .pun .blockpost dt a:visited { + text-decoration: none; + } + +.pun .blockpost dt a:hover, .pun .blockpost dt a:active { + text-decoration: underline; + } + +.pun .postright, .pun .postfootright { + border-left-width: 18em; + border-left-style: solid + } + +#postpreview .postright { + border-left: 0 + } + +.pun .postright { + padding: 0 6px; + } + +.pun .postfootright, .pun .multidelete { + text-align: right + } + +.pun .postmsg { + width:98%; + overflow: hidden; + padding-bottom: 6px; + } + +.pun .postfootright ul, .pun .postfootright div, .pun .postfootright p, +.pun .postfootleft p { + padding: 6px 6px 6px 6px; + } + +.pun .postfootright li { + display: inline; + margin-left: 12px; + } + +.pun .postfootright a:link, .pun .postfootright a:visited { + text-decoration: none + } + +.pun .postfootright a:hover, .pun .postfootright a:active { + text-decoration: underline + } + +.pun .codebox { + border-style: solid; + border-width: 1px; + margin: 0.75em 1em; + padding: 0; + } + +.pun .quotebox { + border-style: solid; + border-width: 1px; + margin: 0.75em 1em; + padding: 0 0.75em; + } + +.pun .quotebox cite { + display: block; + padding: 0.75em 0 0 0; + } + +.pun .quotebox blockquote { + width: 100%; + overflow: hidden + } + +.pun .codebox pre { + overflow: auto; + width: 100%; + overflow-y:hidden + } + +* html .pun .codebox pre { + padding-bottom: 10px; + } + +*+html .pun .codebox pre { + padding-bottom: 10px + } + +.pun .codebox pre code { + display: block; + padding: 0.75em; + } + +.pun .codebox pre.vscroll { + height: 32em; + overflow: auto; + overflow-y: auto + } + +.pun .postmsg img { + vertical-align: bottom; + } + +.pun .postsignature hr { + margin-left: 0px; + width: 200px; + text-align: left; + height: 1px; + border:none + } + +.pun .postmsg .postimg img { + max-width: 98%; + vertical-align: middle; +} + +.pun .postmsg .postimg a:link img, .pun .postmsg .postimg a:visited img { + border-style: solid; + border-width: 2px; +} + +.pun .blockpost label { + padding: 3px 6px; + border-style: solid; + border-width: 1px; + vertical-align: middle; + display: inline-block; + } + +.pun .blockpost label * { + vertical-align: middle; + margin: 0; + padding: 0; + } + +/****************************************************************/ +/* 9. HELP FILES AND MISC. */ +/****************************************************************/ + +#punhelp h2 { + margin-top: 12px + } + +#punhelp div.box { + padding: 10px + } + +#debugtime { + margin-top: -12px; + text-align: center; + } + +/***************************************************************** +COLOUR SCHEME +*****************************************************************/ + +/* Background / Text +----------------------------------------------------------------*/ + +body { + background: #2a2a2a; + color: #d4d4d4 + } + +.pun { + color: #d4d4d4 + } + +.pun .box, #adminconsole fieldset th { + background-color: #383838 + } + +.pun td.tc2, .pun td.tc3, .pun td.tcmod, #postpreview, #viewprofile dd, .pun .forminfo, +#brdfooter #modcontrols, #adminconsole fieldset td, .pun .blockmenu .box, #adstats dd { + background-color: #424242 + } + +.pun h2, #brdmenu { + background-color: #565656; + color: #d4d4d4 + } + +.pun th { + background-color: #484848 + } + +.pun legend { + color: #f6b620 + } + +.pun .blockmenu li.isactive a, #posterror li strong { + color: #d4d4d4 + } + +.pun .usercontent * { + background: transparent; + color: #d4d4d4 + } + +.pun textarea, .pun input, .pun select { + background-color: #2a2a2a; + color: #d4d4d4 + } + +/* Posts +----------------------------------------------------------------*/ + +.pun .blockpost .box, .pun .postright, .pun .postfootright, .pun .deletemsg { + background-color: #383838 + } + +.pun .postright, .pun .postfootright { + border-left-color: #424242 + } + +.pun .postleft, .pun .postfootleft, .pun .blockpost label, .pun .codebox, .pun .quotebox { + background-color: #424242 + } + +.pun .blockpost h2 { + background-color: #565656 + } + +.pun .blockpost h2 span.conr { + color: #a19e96 + } + +.pun .postmsg ins, #punhelp samp ins { + background-color: #ff0; + } + +.pun hr { + background-color: #606060; + color: #606060 + } + +/* Borders +----------------------------------------------------------------*/ + +.pun .box { + border-color:#565656 + } + +.pun td, #brdfooter #modcontrols { + border-color: #565656 + } + +.pun th, .pun fieldset { + border-color: #484848 + } + +#adminconsole td, #adminconsole th { + border-color: #383838 + } + +.pun .quotebox, .pun .codebox, .pun .forminfo, +.pun .blockpost label, .pun .deletemsg { + border-color: #565656 + } + +/* Links +----------------------------------------------------------------*/ + +.pun a:link, .pun a:visited { + color: #f6b620 + } + +.pun a:hover, .pun a:active, .pun a:focus { + color: #ffee40 + } + +.pun .postmsg .postimg a:link img, .pun .postmsg .postimg a:visited img { + border-color: #f6b620; +} + +.pun .postmsg .postimg a:hover img, .pun .postmsg .postimg a:active img, .pun .postmsg .postimg a:focus img { + border-color: #ffee40; +} + +.pun h2 a:link, .pun h2 a:visited, +#brdmenu a:link, #brdmenu a:visited { + color: #d4d4d4 + } + +.pun h2 a:hover, .pun h2 a:active, +#brdmenu a:hover, #brdmenu a:active { + color: #d4d4d4 + } + +.pun .postreport a:link, .pun .postreport a:visited, +.pun .iclosed td.tcl a:link, .pun .iclosed td.tcl a:visited { + color: #888 + } + +.pun .postreport a:hover, .pun .postreport a:active, +.pun .iclosed td.tcl a:hover, .pun .iclosed td.tcl a:active { + color: #aaa + } + +.pun .maintenancelink a:link, .pun .maintenancelink a:visited { + color: #ff4000 + } + +.pun .maintenancelink a:hover, .pun .maintenancelink a:active { + color: #ff5010 + } + +/* Status Indicators +----------------------------------------------------------------*/ + +.pun .icon { + border-color: #484848 #404040 #3c3c3c #444444 + } + +.pun .iredirect .icon { + border-color: #383838 #383838 #383838 #383838 + } + +.pun .inew .icon { + border-color: #f6b620 #ecae1f #d09a1b #e1a61d + } diff --git a/style/Oxygen.css b/style/Oxygen.css new file mode 100644 index 0000000..4d0fe79 --- /dev/null +++ b/style/Oxygen.css @@ -0,0 +1,1086 @@ +/***************************************************************** +1. INITIAL SETTINGS +*****************************************************************/ + +/* Limited Reset +----------------------------------------------------------------*/ + +.pun table, .pun div, .pun form, .pun p, .pun h1, .pun h2, .pun h3, +.pun h4, .pun h5, .pun pre, .pun blockquote, .pun ul, .pun ol, .pun li, .pun dl, +.pun dt, .pun dd, .pun th, .pun td, .pun fieldset, .pun img, .pun abbr, .pun cite { + margin: 0; + padding: 0; + border: 0; + } + +.pun ul, .pun ol { + list-style: none + } + + +/* Structural Settings +----------------------------------------------------------------*/ + +.pun .clearer, .pun .nosize { + height: 0; + width: 0; + line-height: 0; + font-size: 0; + overflow: hidden + } + +.pun .clearer, .pun .clearb { + clear: both + } + +.pun .nosize { + position: absolute; + left: -9999em; + text-indent: -9999em; + width: 0; + } + +* html .inbox, * html .inform, * html .pun, * html .tclcon, * html .codebox { + height: 1px + } + +.pun, .pun .inbox, .pun .inform, .pun .tclcon, .pun .codebox { + min-height: 1px + } + + +/* Hidden Elements +----------------------------------------------------------------*/ + +#brdfooter h2, #brdstats h2, #brdstats .conl dt, #brdstats .conr dt, +#modcontrols dt, #searchlinks dt, div.postright h3, span.closedtext, +.pun .required strong span { + position: absolute; + display: block; + overflow: hidden; + width: 0; + left: -9999em; + text-indent: -9999em; + } + +/***************************************************************** +2. TEXT & CONTENT +*****************************************************************/ + +/* Text Defaults +----------------------------------------------------------------*/ + +.pun { + font: 68.75%/1.4545em Verdana, Helvetica, Arial, sans-serif; + } + +.pun table, .pun td, .pun th, .pun input, .pun select, .pun optgroup, .pun textarea, .pun small, .pun samp { + font-size: 1em; + font-family: verdana, helvetica, arial, sans-serif; + } + +.pun pre, .pun code { + font-size: 1.182em; + font-family: consolas, monaco, "bitstream vera sans mono", "courier new", courier, monospace + } + +.pun pre code { + font-size: 1em; + } + +.pun strong { + font-weight: bold; + } + +.pun em { + font-style: italic; + } + + +/* Content Defaults +----------------------------------------------------------------*/ + +.pun p, .pun ul, .pun ol, .pun dl { + font-size: 1em; + padding: 3px 0; + } + +.pun h2 { + font-size: 1em; + font-weight: normal; + padding: 4px 7px; + } + +.pun h3 { + font-size: 1.091em; + padding: 3px 0; + } + +.pun table p, .pun table h3 { + padding: 0; + } + +.pun span.warntext, .pun p.warntext { + font-weight: bold + } + + +/* User Content (Announcements, Rules, Posts) +----------------------------------------------------------------*/ + +.pun .usercontent p, .pun .postmsg p { + padding: 0.75em 0 + } + +.pun .usercontent ul, .pun .postmsg ul { + padding: 0.75em 1em 0.75em 2.5em; + list-style: disc + } + +.pun .usercontent ol, .pun .postmsg ol { + padding: 0.75em 1em 0.75em 2.5em; + list-style: decimal + } + +.pun .usercontent ol.alpha, .pun .postmsg ol.alpha { + list-style: lower-alpha + } + +.pun .usercontent li ol, .pun .usercontent li ul, .pun .postmsg li ol, .pun .postmsg li ul { + padding: 0.25em 1em 0.75em 2.5em + } + +.pun .usercontent li p, .pun .postmsg li p { + padding: 0 + } + +.pun .usercontent h1 { + font-size: 1.4em; + font-weight: bold; + padding: 0.75em 0 0 0 + } + +.pun .usercontent h2 { + font-size: 1.2em; + font-weight: bold; + padding: 0.75em 0 0 0 + } + +.pun .usercontent h3 { + font-size: 1.1em; + font-weight: bold; + padding: 0.75em 0 0 0 + } + +.pun .usercontent h4, .pun .usercontent h5, .pun .usercontent h6 { + font-size: 1em; + font-weight: bold; + padding: 0.75em 0 0 0 + } + +.pun .quotebox cite { + font-weight: bold; + font-style: normal; + padding: 0.75em 0.75em 0 0.75em + } + +.pun span.bbu { + text-decoration: underline + } + +.pun span.bbs, .pun del { + text-decoration: line-through; + } + +.pun .postmsg ins, #punhelp samp ins { + text-decoration: none; + } + +.pun div.postmsg h5, #punhelp h5 { + font-size: 1.1em; + font-weight: bold; + padding: 0.75em 0 0 0; + } + + +/***************************************************************** +3. COMMON STYLES +*****************************************************************/ + +/* Page Layout +----------------------------------------------------------------*/ + +.pun { + margin: 12px 20px + } + +#punredirect, #punmaint, #puninstall, #pundb_update { + margin: 50px 20% 12px 20% + } + + +/* Vertical Element Spacing +----------------------------------------------------------------*/ + +#brdheader { + margin: 0 0 12px 0; + } + +#announce, #brdstats { + margin: 12px 0 12px 0; + } + +.pun .blocktable, .pun .block, .pun .blockform, .pun .block2col, #postreview { + margin-bottom: 12px + } + +#punindex .blocktable, .pun .blockpost { + margin-bottom: 6px + } + +#postreview .blockpost { + margin-bottom: -1px; + } + +.pun .block2col .blockform, .pun .block2col .block { + margin-bottom: 0px + } + +.pun .linkst, .pun .linksb { + margin-top: -12px + } + +.pun .postlinksb { + margin-top: -6px + } + + +/* External Borders +----------------------------------------------------------------*/ + +.pun .box { + border-style: solid; + border-width: 1px; + } + +#brdheader .box { + border-top-width: 4px; + } + +/* Default Internal Spacing +----------------------------------------------------------------*/ + +.pun .block .inbox, .pun .blockmenu .inbox { + padding: 3px 6px + } + +/***************************************************************** +4. COMMON BOARD ELEMENTS +*****************************************************************/ + +/* Board Header +----------------------------------------------------------------*/ + +#brdtitle h1 { + font-size: 1.454em; + font-weight: bold; + line-height: 1em; + padding: 3px 0 0 0; + } + +#brddesc { + padding: 3px 0; + } + +#brddesc * { + padding-top: 0; + padding-bottom: 0; + } + +#brdmenu li { + display: inline; + margin-right: 12px; + } + +#brdmenu a:link, #brdmenu a:visited { + text-decoration: none + } + +#brdmenu a:hover, #brdmenu a:active { + text-decoration: underline + } + +#brdwelcome .conl { + float: left; + } + +#brdwelcome .conr { + float: right; + text-align: right; + } + +/* Breadcrumbs and Post Links +----------------------------------------------------------------*/ + +.pun .linkst { + padding: 8px 6px 3px 6px + } + +.pun .linksb, .pun .postlinksb { + padding: 3px 6px 8px 6px + } + +.pun .crumbs { + clear: both; + width: 100%; + overflow: hidden; + } + +.pun .crumbs li { + display: inline; + white-space: nowrap; + font-weight: bold; + } + +.pun .pagelink { + float: left; + white-space: nowrap; + } + +.pun .postlink { + font-weight: bold; + white-space: nowrap; + } + +.pun .postlink, .pun .modbuttons { + float: right; + text-align: right; + } + +.pun .modbuttons { + padding: 1px 0; + white-space: nowrap; + } + +.pun .modbuttons input { + margin-left: 6px; + } + +.pun .postlink a:link, .pun .postlink a:visited { + text-decoration: none + } + +.pun .postlink a:hover, .pun .postlink a:active { + text-decoration: underline; + } + + +/* Board Footer +----------------------------------------------------------------*/ + +#brdfooter .conl { + float: left; + } + +#brdfooter .conr { + float: right; + text-align: right; + } + +#brdfooter #modcontrols { + border-bottom-style: solid; + border-bottom-width: 1px; + text-align: center; + } + +#brdfooter #modcontrols dd { + display: inline; + margin:0 6px; + } + + +/* Board Stats +----------------------------------------------------------------*/ + +#brdstats .conl { + float: left; + } + +#brdstats .conr { + float: right; + text-align: right; + } + +#onlinelist dd, #onlinelist dt { + display: inline; + } + + +/***************************************************************** +5. MAIN TABLES +*****************************************************************/ + +.pun table { + width: 100%; + border-collapse: collapse; + border-spacing: 0; + empty-cells: show; + } + +.pun .blocktable table { + table-layout: fixed; + } + +.pun td, .pun th { + padding: 4px 6px; + line-height: 1.273em; + text-align: left; + font-weight: normal; + } + +.pun td { + border-style: solid none none solid; + border-width: 1px; + } + +.pun .tcl { + border-left: 0; + width: auto; + } + +.pun .tc2, .pun .tc3, .pun .tcmod { + width: 10%; + text-align: center; + padding: 4px 0; + } + +.pun .tcr { + width: 30%; + } + +.pun .tcl h3 { + font-size: 1.091em; + font-weight: bold; + } + +.pun .tcl h3 span.newtext { + font-size: 0.917em; + } + +.pun .tcl span.newtext, .pun .tcl span.pagestext { + white-space: nowrap; + font-weight: normal; + } + +.pun td span.byuser { + white-space: nowrap; + } + +.pun .tcl p { + padding: 5px 0 0 0 + } + +#punsearch #vf .tc2 { + width: 18%; + text-align: left; + padding: 4px 6px; + } + +#users1 .tcr { + width: 25% + } + +#users1 .tc2 { + width: 25%; + text-align: left; + padding: 4px 6px; + } + +#debug .tcl { + width: 10% + } + +#debug .tcr { + width: 90%; + white-space: normal + } + +#punindex .tcr .byuser { + display: block + } + +.pun .blocktable .tclcon { + padding: 0 11px 0 12px; + overflow: hidden; + height: 1%; + min-height: 1px; + position: relative; + } + +.pun .blocktable .tclcon div { + width: 100%; + overflow: hidden; + } + +.pun .icon { + border-width: 7px; + border-style: solid; + height: 0; + width: 0; + overflow: hidden; + float: left; + } + +.pun .icon div { + position: absolute; + left: -9999em; + text-indent: -9999em; + height: 0; + } + +.pun .iposted .ipost { + position: absolute; + left: 0; + font-weight: bold; + width: 8px; + padding-left: 4px; + text-align: center; + top: 0; + } + +/***************************************************************** +6. MAIN FORMS +*****************************************************************/ + +.pun .blockform form, .pun .fakeform { + PADDING: 20px 20px 15px 20px + } + +.pun .forminfo { + margin-bottom: 12px; + padding: 9px 10px; + border-style: solid; + border-width: 1px; + } + +.pun .forminfo h3 { + font-weight: bold; + } + +.pun .inform { + padding-bottom: 12px + } + +.pun fieldset { + padding: 0px 12px 0px 12px; + border-style: solid; + border-width: 1px + } + +.pun legend { + padding: 0px 6px + } + +.pun .infldset { + padding: 9px 0px 12px 0 + } + +.pun label { + display: block; + padding: 3px 0 + } + +.pun label.conl { + float: left; + overflow: visible; + margin-right: 10px + } + +.pun select { + padding-top: 1px; + padding-bottom: 1px; + } + +.pun fieldset .rbox { + } + +.pun fieldset .rbox br { + display: none; + } + +.pun fieldset .rbox label { + padding: 3px 0 3px 25px; + position: relative; + vertical-align: middle; + } + +.pun fieldset .rbox input { + margin: 0 9px 0 -25px; + padding: 0; + width: 16px; + position: relative; + vertical-align: middle; + } + +.pun .txtarea { + width: 75% + } + +.pun .txtarea textarea, .pun input.longinput { + width: 100% + } + +.pun .bblinks { + padding-bottom: 10px; + padding-left: 4px + } + +.pun .bblinks li { + display: inline; + padding-right: 20px + } + +.pun .blockform .buttons { + padding-left: 12px; + } + +.pun .blockform .buttons input { + margin-right: 8px; + } + +#posterror ul { + list-style: square; + padding: 3px 0 3px 24px; + } + +.pun .deletemsg { + border-style: solid; + border-width: 1px; + padding: 6px 15px; + } + +.pun p.actions span { + margin-right: 12px; + } + +/***************************************************************** +7. PROFILES AND ADMIN +*****************************************************************/ + +.pun .block2col { + padding-bottom: 1px + } + +.pun .block2col .blockform, .pun .block2col .block { + margin-left: 17em + } + +.pun .blockmenu { + float:left; + width: 16em + } + +.pun .blockmenu li { + padding: 3px 0; + font-weight: bold; + } + +.pun .blockmenu a:link, .pun .blockmenu a:visited { + text-decoration: none + } + +.pun .blockmenu a:hover, .pun .blockmenu a:active { + text-decoration: underline + } + +#viewprofile dl { + float: left; + width: 100%; + overflow: hidden + } + +#viewprofile dd { + margin-left: 14em; + padding: 3px; + } + +#viewprofile dt { + float: left; + width: 13em; + margin: 3px 0; + } + +#profileavatar img { + float: right; + margin-left: 1em + } + +/***************************************************************** +8. MAIN POSTS +*****************************************************************/ + +.pun .blockpost h2 a:link, .pun .blockpost h2 a:visited { + text-decoration: none; + } + +.pun .blockpost h2 a:hover, .pun .blockpost h2 a:active { + text-decoration: underline; + } + +.pun .blockpost h2 .conr { + float: right; + text-align: right; + } + +#punsearch .blockpost h2 span { + white-space: nowrap; + } + +.pun .blockpost .box { + overflow: hidden; + } + +.pun .postleft, .pun .postfootleft { + float:left; + width: 18em; + position: relative; + overflow: hidden; + } + +.pun .postleft dl { + padding: 0.75em 6px; + } + +.pun .postleft .usercontacts, .pun .postleft .icon { + margin-top: 6px + } + +.pun .postleft .postavatar, .pun .postleft .usertitle { + margin-bottom: 6px; + display: block; + } + +.pun .blockpost dt { + font-size: 1.091em; + font-weight: bold; + } + +.pun .blockpost dt a:link, .pun .blockpost dt a:visited { + text-decoration: none; + } + +.pun .blockpost dt a:hover, .pun .blockpost dt a:active { + text-decoration: underline; + } + +.pun .postright, .pun .postfootright { + border-left-width: 18em; + border-left-style: solid + } + +#postpreview .postright { + border-left: 0 + } + +.pun .postright { + padding: 0 6px; + } + +.pun .postfootright, .pun .multidelete { + text-align: right + } + +.pun .postmsg { + width:98%; + overflow: hidden; + padding-bottom: 6px; + } + +.pun .postfootright ul, .pun .postfootright div, .pun .postfootright p, +.pun .postfootleft p { + padding: 6px 6px 6px 6px; + } + +.pun .postfootright li { + display: inline; + margin-right: 12px; + } + +.pun .postfootright a:link, .pun .postfootright a:visited { + text-decoration: none + } + +.pun .postfootright a:hover, .pun .postfootright a:active { + text-decoration: underline + } + +.pun .codebox { + border-style: solid; + border-width: 1px; + margin: 0.75em 1em; + padding: 0; + } + +.pun .quotebox { + border-style: solid; + border-width: 1px; + margin: 0.75em 1em; + padding: 0 0.75em; + } + +.pun .quotebox cite { + display: block; + padding: 0.75em 0 0 0; + } + +.pun .quotebox blockquote { + width: 100%; + overflow: hidden + } + +.pun .codebox pre { + overflow: auto; + width: 100%; + overflow-y:hidden + } + +* html .pun .codebox pre { + padding-bottom: 10px; + } + +*+html .pun .codebox pre { + padding-bottom: 10px + } + +.pun .codebox pre code { + display: block; + padding: 0.75em; + } + +.pun .codebox pre.vscroll { + height: 32em; + overflow: auto; + overflow-y: auto + } + +.pun .postmsg img { + vertical-align: bottom; + } + +.pun .postsignature hr { + margin-left: 0px; + width: 200px; + text-align: left; + height: 1px; + border:none + } + +.pun .postmsg .postimg img { + max-width: 98%; + vertical-align: middle; +} + +.pun .postmsg .postimg a:link img, .pun .postmsg .postimg a:visited img { + border-style: solid; + border-width: 2px; +} + +.pun .blockpost label { + padding: 3px 6px; + border-style: solid; + border-width: 1px; + vertical-align: middle; + display: inline-block; + } + +.pun .blockpost label * { + vertical-align: middle; + margin: 0; + padding: 0; + } + +/****************************************************************/ +/* 9. HELP FILES AND MISC. */ +/****************************************************************/ + +#punhelp h2 { + margin-top: 12px + } + +#punhelp div.box { + padding: 10px + } + +#debugtime { + margin-top: -12px; + text-align: center; + } + +/***************************************************************** +COLOUR SCHEME +*****************************************************************/ + +/* Background / Text +----------------------------------------------------------------*/ + +body { + background: #fff; + color: #333 + } + +.pun { + color: #333 + } + +.pun .box, #adminconsole fieldset th { + background-color: #f1f1f1 + } + +.pun td.tc2, .pun td.tc3, .pun td.tcmod, #postpreview, #viewprofile dd, .pun .forminfo, +#adminconsole fieldset td, .pun .blockmenu .box, #adstats dd, #brdfooter #modcontrols { + background-color: #dedfdf + } + +.pun h2, #brdmenu { + background-color: #0066b9; + color: #fff + } + +.pun th { + background-color: #d1d1d1 + } + +.pun legend { + color: #005cb1 + } + +.pun .blockmenu li.isactive a, #posterror li strong { + color: #333 + } + +.pun .usercontent * { + background: transparent; + color: #333 + } + +/* Posts +----------------------------------------------------------------*/ + +.pun .blockpost .box, .pun .postright, .pun .postfootright, .pun .deletemsg { + background-color: #dedfdf + } + +.pun .postright, .pun .postfootright { + border-left-color: #f1f1f1 + } + +.pun .postleft, .pun .postfootleft, .pun .blockpost label, .pun .codebox, .pun .quotebox { + background-color: #f1f1f1 + } + +#punhelp .codebox, #punhelp .quotebox { + background-color: #f9f9f9; + } + +.pun .blockpost h2 { + background-color: #006fc9 + } + +.pun .blockpost h2 span.conr { + color: #aabdcd + } + +.pun .postmsg ins, #punhelp samp ins { + background-color: #ff0; + } + +.pun hr { + background-color: #333; + color: #333 + } + +/* Borders +----------------------------------------------------------------*/ + +.pun .box { + border-color: #0066b9 + } + +.pun td, #brdfooter #modcontrols { + border-color: #bbcede + } + +.pun th, .pun fieldset { + border-color: #d1d1d1 + } + +#adminconsole td, #adminconsole th { + border-color: #f1f1f1 + } + +.pun .quotebox, .pun .codebox, .pun .forminfo, +.pun .blockpost label, .pun .deletemsg { + border-color: #aca899 #fff #fff #aca899 + } + +/* Links +----------------------------------------------------------------*/ + +.pun a:link, .pun a:visited { + color: #005cb1 + } + +.pun a:hover, .pun a:active, .pun a:focus { + color: #b42000 + } + +.pun .postmsg .postimg a:link img, .pun .postmsg .postimg a:visited img { + border-color: #005cb1; +} + +.pun .postmsg .postimg a:hover img, .pun .postmsg .postimg a:active img, .pun .postmsg .postimg a:focus img { + border-color: #b42000; +} + +.pun h2 a:link, .pun h2 a:visited, +#brdmenu a:link, #brdmenu a:visited { + color: #fff + } + +.pun h2 a:hover, .pun h2 a:active, +#brdmenu a:hover, #brdmenu a:active { + color: #fff + } + +.pun .postreport a:link, .pun .postreport a:visited, +.pun .iclosed td.tcl a:link, .pun .iclosed td.tcl a:visited { + color: #888 + } + +.pun .postreport a:hover, .pun .postreport a:active, +.pun .iclosed td.tcl a:hover, .pun .iclosed td.tcl a:active { + color: #aaa + } + +.pun .maintenancelink a:link, .pun .maintenancelink a:visited { + color: #b42000 + } + +.pun .maintenancelink a:hover, .pun .maintenancelink a:active { + color: #b42000 + } + +/* Status Indicators +----------------------------------------------------------------*/ + +.pun .icon { + border-color: #e6e6e6 #dedede #dadada #e2e2e2 + } + +.pun .iredirect .icon { + border-color: #f1f1f1 #f1f1f1 #f1f1f1 #f1f1f1 + } + +.pun .inew .icon { + border-color: #0080d7 #0065c0 #0058b3 #0072ca + } diff --git a/style/Radium.css b/style/Radium.css new file mode 100644 index 0000000..505c92e --- /dev/null +++ b/style/Radium.css @@ -0,0 +1,1086 @@ +/***************************************************************** +1. INITIAL SETTINGS +*****************************************************************/ + +/* Limited Reset +----------------------------------------------------------------*/ + +.pun table, .pun div, .pun form, .pun p, .pun h1, .pun h2, .pun h3, +.pun h4, .pun h5, .pun pre, .pun blockquote, .pun ul, .pun ol, .pun li, .pun dl, +.pun dt, .pun dd, .pun th, .pun td, .pun fieldset, .pun img, .pun abbr, .pun cite { + margin: 0; + padding: 0; + border: 0; + } + +.pun ul, .pun ol { + list-style: none + } + + +/* Structural Settings +----------------------------------------------------------------*/ + +.pun .clearer, .pun .nosize { + height: 0; + width: 0; + line-height: 0; + font-size: 0; + overflow: hidden + } + +.pun .clearer, .pun .clearb { + clear: both + } + +.pun .nosize { + position: absolute; + left: -9999em; + text-indent: -9999em; + width: 0; + } + +* html .inbox, * html .inform, * html .pun, * html .tclcon, * html .codebox { + height: 1px + } + +.pun, .pun .inbox, .pun .inform, .pun .tclcon, .pun .codebox { + min-height: 1px + } + + +/* Hidden Elements +----------------------------------------------------------------*/ + +#brdfooter h2, #brdstats h2, #brdstats .conl dt, #brdstats .conr dt, +#modcontrols dt, #searchlinks dt, div.postright h3, span.closedtext, +.pun .required strong span { + position: absolute; + display: block; + overflow: hidden; + width: 0; + left: -9999em; + text-indent: -9999em; + } + +/***************************************************************** +2. TEXT & CONTENT +*****************************************************************/ + +/* Text Defaults +----------------------------------------------------------------*/ + +.pun { + font: 68.75%/1.4545em Verdana, Helvetica, Arial, sans-serif; + } + +.pun table, .pun td, .pun th, .pun input, .pun select, .pun optgroup, .pun textarea, .pun samp { + font-size: 1em; + font-family: verdana, helvetica, arial, sans-serif; + } + +.pun pre, .pun code { + font-size: 1.182em; + font-family: consolas, monaco, "bitstream vera sans mono", "courier new", courier, monospace + } + +.pun pre code { + font-size: 1em; + } + +.pun strong { + font-weight: bold; + } + +.pun em { + font-style: italic; + } + + +/* Content Defaults +----------------------------------------------------------------*/ + +.pun p, .pun ul, .pun ol, .pun dl { + font-size: 1em; + padding: 3px 0; + } + +.pun h2 { + font-size: 1em; + font-weight: normal; + padding: 4px 7px; + } + +.pun h3 { + font-size: 1.091em; + padding: 3px 0; + } + +.pun table p, .pun table h3 { + padding: 0; + } + +.pun span.warntext, .pun p.warntext { + font-weight: bold + } + +/* User Content (Announcements, Rules, Posts) +----------------------------------------------------------------*/ + +.pun .usercontent p, .pun .postmsg p { + padding: 0.75em 0 + } + +.pun .usercontent ul, .pun .postmsg ul { + padding: 0.75em 1em 0.75em 2.5em; + list-style: disc + } + +.pun .usercontent ol, .pun .postmsg ol { + padding: 0.75em 1em 0.75em 2.5em; + list-style: decimal + } + +.pun .usercontent ol.alpha, .pun .postmsg ol.alpha { + list-style: lower-alpha + } + +.pun .usercontent li ol, .pun .usercontent li ul, .pun .postmsg li ol, .pun .postmsg li ul { + padding: 0.25em 1em 0.75em 2.5em + } + +.pun .usercontent li p, .pun .postmsg li p { + padding: 0 + } + +.pun .usercontent h1 { + font-size: 1.4em; + font-weight: bold; + padding: 0.75em 0 0 0 + } + +.pun .usercontent h2 { + font-size: 1.2em; + font-weight: bold; + padding: 0.75em 0 0 0 + } + +.pun .usercontent h3 { + font-size: 1.1em; + font-weight: bold; + padding: 0.75em 0 0 0 + } + +.pun .usercontent h4, .pun .usercontent h5, .pun .usercontent h6 { + font-size: 1em; + font-weight: bold; + padding: 0.75em 0 0 0 + } + +.pun .quotebox cite { + font-weight: bold; + font-style: normal; + padding: 0.75em 0.75em 0 0.75em + } + +.pun span.bbu { + text-decoration: underline + } + +.pun span.bbs, .pun del { + text-decoration: line-through; + } + +.pun .postmsg ins, #punhelp samp ins { + text-decoration: none; + } + +.pun div.postmsg h5, #punhelp h5 { + font-size: 1.1em; + font-weight: bold; + padding: 0.75em 0 0 0; + } + + +/***************************************************************** +3. COMMON STYLES +*****************************************************************/ + +/* Page Layout +----------------------------------------------------------------*/ + +.pun { + margin: 12px 20px + } + +#punredirect, #punmaint, #puninstall, #pundb_update { + margin: 50px 20% 12px 20% + } + + +/* Vertical Element Spacing +----------------------------------------------------------------*/ + +#brdheader { + margin: 0 0 12px 0; + } + +#announce, #brdstats { + margin: 12px 0 12px 0; + } + +.pun .blocktable, .pun .block, .pun .blockform, .pun .block2col, #postreview { + margin-bottom: 12px + } + +#punindex .blocktable, .pun .blockpost { + margin-bottom: 6px + } + +#postreview .blockpost { + margin-bottom: -1px; + } + +.pun .block2col .blockform, .pun .block2col .block { + margin-bottom: 0px + } + +.pun .linkst, .pun .linksb { + margin-top: -12px + } + +.pun .postlinksb { + margin-top: -6px + } + + +/* External Borders +----------------------------------------------------------------*/ + +.pun .box { + border-style: solid; + border-width: 1px; + } + +#brdheader .box { + border-top-width: 4px; + } + +/* Default Internal Spacing +----------------------------------------------------------------*/ + +.pun .block .inbox, .pun .blockmenu .inbox { + padding: 3px 6px + } + +/***************************************************************** +4. COMMON BOARD ELEMENTS +*****************************************************************/ + +/* Board Header +----------------------------------------------------------------*/ + +#brdtitle h1 { + font-size: 1.454em; + font-weight: bold; + line-height: 1em; + padding: 3px 0 0 0; + } + +#brddesc { + padding: 3px 0; + } + +#brddesc * { + padding-top: 0; + padding-bottom: 0; + } + +#brdmenu li { + display: inline; + margin-right: 12px; + } + +#brdmenu a:link, #brdmenu a:visited { + text-decoration: none + } + +#brdmenu a:hover, #brdmenu a:active { + text-decoration: underline + } + +#brdwelcome .conl { + float: left; + } + +#brdwelcome .conr { + float: right; + text-align: right; + } + +/* Breadcrumbs and Post Links +----------------------------------------------------------------*/ + +.pun .linkst { + padding: 8px 6px 3px 6px + } + +.pun .linksb, .pun .postlinksb { + padding: 3px 6px 8px 6px + } + +.pun .crumbs { + clear: both; + width: 100%; + overflow: hidden; + } + +.pun .crumbs li { + display: inline; + white-space: nowrap; + font-weight: bold; + } + +.pun .pagelink { + float: left; + white-space: nowrap; + } + +.pun .postlink { + font-weight: bold; + white-space: nowrap; + } + +.pun .postlink, .pun .modbuttons { + float: right; + text-align: right; + } + +.pun .modbuttons { + padding: 1px 0; + white-space: nowrap; + } + +.pun .modbuttons input { + margin-left: 6px; + } + +.pun .postlink a:link, .pun .postlink a:visited { + text-decoration: none + } + +.pun .postlink a:hover, .pun .postlink a:active { + text-decoration: underline; + } + + +/* Board Footer +----------------------------------------------------------------*/ + +#brdfooter .conl { + float: left; + } + +#brdfooter .conr { + float: right; + text-align: right; + } + +#brdfooter #modcontrols { + border-bottom-style: solid; + border-bottom-width: 1px; + text-align: center; + } + +#brdfooter #modcontrols dd { + display: inline; + margin:0 6px; + } + + +/* Board Stats +----------------------------------------------------------------*/ + +#brdstats .conl { + float: left; + } + +#brdstats .conr { + float: right; + text-align: right; + } + +#onlinelist dd, #onlinelist dt { + display: inline; + } + + +/***************************************************************** +5. MAIN TABLES +*****************************************************************/ + +.pun table { + width: 100%; + border-collapse: collapse; + border-spacing: 0; + empty-cells: show; + } + +.pun .blocktable table { + table-layout: fixed; + } + +.pun td, .pun th { + padding: 4px 6px; + line-height: 1.273em; + text-align: left; + font-weight: normal; + } + +.pun td { + border-style: solid none none solid; + border-width: 1px; + } + +.pun .tcl { + border-left: 0; + width: auto; + } + +.pun .tc2, .pun .tc3, .pun .tcmod { + width: 10%; + text-align: center; + padding: 4px 0; + } + +.pun .tcr { + width: 30%; + } + +.pun .tcl h3 { + font-size: 1.091em; + font-weight: bold; + } + +.pun .tcl h3 span.newtext { + font-size: 0.917em; + } + +.pun .tcl span.newtext, .pun .tcl span.pagestext { + white-space: nowrap; + font-weight: normal; + } + +.pun td span.byuser { + white-space: nowrap; + } + +.pun .tcl p { + padding: 5px 0 0 0 + } + +#punsearch #vf .tc2 { + width: 18%; + text-align: left; + padding: 4px 6px; + } + +#users1 .tcr { + width: 25% + } + +#users1 .tc2 { + width: 25%; + text-align: left; + padding: 4px 6px; + } + +#debug .tcl { + width: 10% + } + +#debug .tcr { + width: 90%; + white-space: normal + } + +#punindex .tcr .byuser { + display: block + } + +.pun .blocktable .tclcon { + padding: 0 11px 0 12px; + overflow: hidden; + height: 1%; + min-height: 1px; + position: relative; + } + +.pun .blocktable .tclcon div { + width: 100%; + overflow: hidden; + } + +.pun .icon { + border-width: 7px; + border-style: solid; + height: 0; + width: 0; + overflow: hidden; + float: left; + } + +.pun .icon div { + position: absolute; + left: -9999em; + text-indent: -9999em; + height: 0; + } + +.pun .iposted .ipost { + position: absolute; + left: 0; + font-weight: bold; + width: 8px; + padding-left: 4px; + text-align: center; + top: 0; + } + +/***************************************************************** +6. MAIN FORMS +*****************************************************************/ + +.pun .blockform form, .pun .fakeform { + PADDING: 20px 20px 15px 20px + } + +.pun .forminfo { + margin-bottom: 12px; + padding: 9px 10px; + border-style: solid; + border-width: 1px; + } + +.pun .forminfo h3 { + font-weight: bold; + } + +.pun .inform { + padding-bottom: 12px + } + +.pun fieldset { + padding: 0px 12px 0px 12px; + border-style: solid; + border-width: 1px + } + +.pun legend { + padding: 0px 6px + } + +.pun .infldset { + padding: 9px 0px 12px 0 + } + +.pun label { + display: block; + padding: 3px 0 + } + +.pun label.conl { + float: left; + overflow: visible; + margin-right: 10px + } + +.pun select { + padding-top: 1px; + padding-bottom: 1px; + } + +.pun fieldset .rbox { + } + +.pun fieldset .rbox br { + display: none; + } + +.pun fieldset .rbox label { + padding: 3px 0 3px 25px; + position: relative; + vertical-align: middle; + } + +.pun fieldset .rbox input { + margin: 0 9px 0 -25px; + padding: 0; + width: 16px; + position: relative; + vertical-align: middle; + } + +.pun .txtarea { + width: 75% + } + +.pun .txtarea textarea, .pun input.longinput { + width: 100% + } + +.pun .bblinks { + padding-bottom: 10px; + padding-left: 4px + } + +.pun .bblinks li { + display: inline; + padding-right: 20px + } + +.pun .blockform .buttons { + padding-left: 12px; + } + +.pun .blockform .buttons input { + margin-right: 8px; + } + +#posterror ul { + list-style: square; + padding: 3px 0 3px 24px; + } + +.pun .deletemsg { + border-style: solid; + border-width: 1px; + padding: 6px 15px; + } + +.pun p.actions span { + margin-right: 12px; + } + +/***************************************************************** +7. PROFILES AND ADMIN +*****************************************************************/ + +.pun .block2col { + padding-bottom: 1px + } + +.pun .block2col .blockform, .pun .block2col .block { + margin-left: 17em + } + +.pun .blockmenu { + float:left; + width: 16em + } + +.pun .blockmenu li { + padding: 3px 0; + font-weight: bold; + } + +.pun .blockmenu a:link, .pun .blockmenu a:visited { + text-decoration: none + } + +.pun .blockmenu a:hover, .pun .blockmenu a:active { + text-decoration: underline + } + +#viewprofile dl { + float: left; + width: 100%; + overflow: hidden + } + +#viewprofile dd { + margin-left: 14em; + padding: 3px; + } + +#viewprofile dt { + float: left; + width: 13em; + margin: 3px 0; + } + +#profileavatar img { + float: right; + margin-left: 1em + } + +/***************************************************************** +8. MAIN POSTS +*****************************************************************/ + +.pun .blockpost h2 a:link, .pun .blockpost h2 a:visited { + text-decoration: none; + } + +.pun .blockpost h2 a:hover, .pun .blockpost h2 a:active { + text-decoration: underline; + } + +.pun .blockpost h2 .conr { + float: right; + text-align: right; + } + +#punsearch .blockpost h2 span { + white-space: nowrap; + } + +.pun .blockpost .box { + overflow: hidden; + } + +.pun .postleft, .pun .postfootleft { + float:left; + width: 18em; + position: relative; + overflow: hidden; + } + +.pun .postleft dl { + padding: 0.75em 6px; + } + +.pun .postleft .usercontacts, .pun .postleft .icon { + margin-top: 6px + } + +.pun .postleft .postavatar, .pun .postleft .usertitle { + margin-bottom: 6px; + display: block; + } + +.pun .blockpost dt { + font-size: 1.091em; + font-weight: bold; + } + +.pun .blockpost dt a:link, .pun .blockpost dt a:visited { + text-decoration: none; + } + +.pun .blockpost dt a:hover, .pun .blockpost dt a:active { + text-decoration: underline; + } + +.pun .postright, .pun .postfootright { + border-left-width: 18em; + border-left-style: solid + } + +#postpreview .postright { + border-left: 0 + } + +.pun .postright { + padding: 0 6px; + } + +.pun .postfootright, .pun .multidelete { + text-align: right + } + +.pun .postmsg { + width:98%; + overflow: hidden; + padding-bottom: 6px; + } + +.pun .postfootright ul, .pun .postfootright div, .pun .postfootright p, +.pun .postfootleft p { + padding: 6px 6px 6px 6px; + } + +.pun .postfootright li { + display: inline; + margin-left: 12px; + } + +.pun .postfootright a:link, .pun .postfootright a:visited { + text-decoration: none + } + +.pun .postfootright a:hover, .pun .postfootright a:active { + text-decoration: underline + } + +.pun .codebox { + border-style: solid; + border-width: 1px; + margin: 0.75em 1em; + padding: 0; + } + +.pun .quotebox { + border-style: solid; + border-width: 1px; + margin: 0.75em 1em; + padding: 0 0.75em; + } + +.pun .quotebox cite { + display: block; + padding: 0.75em 0 0 0; + } + +.pun .quotebox blockquote { + width: 100%; + overflow: hidden + } + +.pun .codebox pre { + overflow: auto; + width: 100%; + overflow-y:hidden + } + +* html .pun .codebox pre { + padding-bottom: 10px; + } + +*+html .pun .codebox pre { + padding-bottom: 10px + } + +.pun .codebox pre code { + display: block; + padding: 0.75em; + } + +.pun .codebox pre.vscroll { + height: 32em; + overflow: auto; + overflow-y: auto + } + +.pun .postmsg img { + vertical-align: bottom; + } + +.pun .postsignature hr { + margin-left: 0px; + width: 200px; + text-align: left; + height: 1px; + border:none + } + +.pun .postmsg .postimg img { + max-width: 98%; + vertical-align: middle; +} + +.pun .postmsg .postimg a:link img, .pun .postmsg .postimg a:visited img { + border-style: solid; + border-width: 2px; +} + +.pun .blockpost label { + padding: 3px 6px; + border-style: solid; + border-width: 1px; + vertical-align: middle; + display: inline-block; + } + +.pun .blockpost label * { + vertical-align: middle; + margin: 0; + padding: 0; + } + +/****************************************************************/ +/* 9. HELP FILES AND MISC. */ +/****************************************************************/ + +#punhelp h2 { + margin-top: 12px + } + +#punhelp div.box { + padding: 10px + } + +#debugtime { + margin-top: -12px; + text-align: center; + } + +/***************************************************************** +COLOUR SCHEME +*****************************************************************/ + +/* Background / Text +----------------------------------------------------------------*/ + +body { + background: #2a2a2a; + color: #d4d4d4 + } + +.pun { + color: #d4d4d4 + } + +.pun .box, #adminconsole fieldset th { + background-color: #383838 + } + +.pun td.tc2, .pun td.tc3, .pun td.tcmod, #postpreview, #viewprofile dd, .pun .forminfo, +#brdfooter #modcontrols, #adminconsole fieldset td, .pun .blockmenu .box, #adstats dd { + background-color: #424242 + } + +.pun h2, #brdmenu { + background-color: #565656; + color: #d4d4d4 + } + +.pun th { + background-color: #484848 + } + +.pun legend { + color: #60c860 + } + +.pun .blockmenu li.isactive a, #posterror li strong { + color: #d4d4d4 + } + +.pun .usercontent * { + background: transparent; + color: #d4d4d4 + } + +.pun textarea, .pun input, .pun select { + background-color: #2a2a2a; + color: #d4d4d4 + } + +/* Posts +----------------------------------------------------------------*/ + +.pun .blockpost .box, .pun .postright, .pun .postfootright, .pun .deletemsg { + background-color: #383838 + } + +.pun .postright, .pun .postfootright { + border-left-color: #424242 + } + +.pun .postleft, .pun .postfootleft, .pun .blockpost label, .pun .codebox, .pun .quotebox { + background-color: #424242 + } + +.pun .blockpost h2 { + background-color: #565656 + } + +.pun .blockpost h2 span.conr { + color: #a19e96 + } + +.pun .postmsg ins, #punhelp samp ins { + background-color: #ff0; + } + +.pun hr { + background-color: #606060; + color: #606060 + } + +/* Borders +----------------------------------------------------------------*/ + +.pun .box { + border-color:#565656 + } + +.pun td, #brdfooter #modcontrols { + border-color: #565656 + } + +.pun th, .pun fieldset { + border-color: #484848 + } + +#adminconsole td, #adminconsole th { + border-color: #383838 + } + +.pun .quotebox, .pun .codebox, .pun .forminfo, +.pun .blockpost label, .pun .deletemsg { + border-color: #606060 + } + +/* Links +----------------------------------------------------------------*/ + +.pun a:link, .pun a:visited { + color: #60c860 + } + +.pun a:hover, .pun a:active, .pun a:focus { + color: #80ee80 + } + +.pun .postmsg .postimg a:link img, .pun .postmsg .postimg a:visited img { + border-color: #60c860; +} + +.pun .postmsg .postimg a:hover img, .pun .postmsg .postimg a:active img, .pun .postmsg .postimg a:focus img { + border-color: #80ee80; +} + +.pun h2 a:link, .pun h2 a:visited, +#brdmenu a:link, #brdmenu a:visited { + color: #d4d4d4 + } + +.pun h2 a:hover, .pun h2 a:active, +#brdmenu a:hover, #brdmenu a:active { + color: #d4d4d4 + } + +.pun .postreport a:link, .pun .postreport a:visited, +.pun .iclosed td.tcl a:link, .pun .iclosed td.tcl a:visited { + color: #888 + } + +.pun .postreport a:hover, .pun .postreport a:active, +.pun .iclosed td.tcl a:hover, .pun .iclosed td.tcl a:active { + color: #aaa + } + +.pun .maintenancelink a:link, .pun .maintenancelink a:visited { + color: #ff4000 + } + +.pun .maintenancelink a:hover, .pun .maintenancelink a:active { + color: #ff5010 + } + +/* Status Indicators +----------------------------------------------------------------*/ + +.pun .icon { + border-color: #484848 #404040 #3c3c3c #444444 + } + +.pun .iredirect .icon { + border-color: #383838 #383838 #383838 #383838 + } + +.pun .inew .icon { + border-color: #60c860 #54af54 #499849 #59b657 + } diff --git a/style/Sulfur.css b/style/Sulfur.css new file mode 100644 index 0000000..49b3e2d --- /dev/null +++ b/style/Sulfur.css @@ -0,0 +1,1085 @@ +/***************************************************************** +1. INITIAL SETTINGS +*****************************************************************/ + +/* Limited Reset +----------------------------------------------------------------*/ + +.pun table, .pun div, .pun form, .pun p, .pun h1, .pun h2, .pun h3, +.pun h4, .pun h5, .pun pre, .pun blockquote, .pun ul, .pun ol, .pun li, .pun dl, +.pun dt, .pun dd, .pun th, .pun td, .pun fieldset, .pun img, .pun abbr, .pun cite { + margin: 0; + padding: 0; + border: 0; + } + +.pun ul, .pun ol { + list-style: none + } + + +/* Structural Settings +----------------------------------------------------------------*/ + +.pun .clearer, .pun .nosize { + height: 0; + width: 0; + line-height: 0; + font-size: 0; + overflow: hidden + } + +.pun .clearer, .pun .clearb { + clear: both + } + +.pun .nosize { + position: absolute; + left: -9999em; + text-indent: -9999em; + width: 0; + } + +* html .inbox, * html .inform, * html .pun, * html .tclcon, * html .codebox { + height: 1px + } + +.pun, .pun .inbox, .pun .inform, .pun .tclcon, .pun .codebox { + min-height: 1px + } + + +/* Hidden Elements +----------------------------------------------------------------*/ + +#brdfooter h2, #brdstats h2, #brdstats .conl dt, #brdstats .conr dt, +#modcontrols dt, #searchlinks dt, div.postright h3, span.closedtext, +.pun .required strong span { + position: absolute; + display: block; + overflow: hidden; + width: 0; + left: -9999em; + text-indent: -9999em; + } + +/***************************************************************** +2. TEXT & CONTENT +*****************************************************************/ + +/* Text Defaults +----------------------------------------------------------------*/ + +.pun { + font: 68.75%/1.4545em Verdana, Helvetica, Arial, sans-serif; + } + +.pun table, .pun td, .pun th, .pun input, .pun select, .pun optgroup, .pun textarea, .pun samp { + font-size: 1em; + font-family: verdana, helvetica, arial, sans-serif; + } + +.pun pre, .pun code { + font-size: 1.182em; + font-family: consolas, monaco, "bitstream vera sans mono", "courier new", courier, monospace + } + +.pun pre code { + font-size: 1em; + } + +.pun strong { + font-weight: bold; + } + +.pun em { + font-style: italic; + } + + +/* Content Defaults +----------------------------------------------------------------*/ + +.pun p, .pun ul, .pun ol, .pun dl { + font-size: 1em; + padding: 3px 0; + } + +.pun h2 { + font-size: 1em; + font-weight: normal; + padding: 4px 7px; + } + +.pun h3 { + font-size: 1.091em; + padding: 3px 0; + } + +.pun table p, .pun table h3 { + padding: 0; + } + +.pun span.warntext, .pun p.warntext { + font-weight: bold + } + +/* User Content (Announcements, Rules, Posts) +----------------------------------------------------------------*/ + +.pun .usercontent p, .pun .postmsg p { + padding: 0.75em 0 + } + +.pun .usercontent ul, .pun .postmsg ul { + padding: 0.75em 1em 0.75em 2.5em; + list-style: disc + } + +.pun .usercontent ol, .pun .postmsg ol { + padding: 0.75em 1em 0.75em 2.5em; + list-style: decimal + } + +.pun .usercontent ol.alpha, .pun .postmsg ol.alpha { + list-style: lower-alpha + } + +.pun .usercontent li ol, .pun .usercontent li ul, .pun .postmsg li ol, .pun .postmsg li ul { + padding: 0.25em 1em 0.75em 2.5em + } + +.pun .usercontent li p, .pun .postmsg li p { + padding: 0 + } + +.pun .usercontent h1 { + font-size: 1.4em; + font-weight: bold; + padding: 0.75em 0 0 0 + } + +.pun .usercontent h2 { + font-size: 1.2em; + font-weight: bold; + padding: 0.75em 0 0 0 + } + +.pun .usercontent h3 { + font-size: 1.1em; + font-weight: bold; + padding: 0.75em 0 0 0 + } + +.pun .usercontent h4, .pun .usercontent h5, .pun .usercontent h6 { + font-size: 1em; + font-weight: bold; + padding: 0.75em 0 0 0 + } + +.pun .quotebox cite { + font-weight: bold; + font-style: normal; + padding: 0.75em 0.75em 0 0.75em + } + +.pun span.bbu { + text-decoration: underline + } + +.pun span.bbs, .pun del { + text-decoration: line-through; + } + +.pun .postmsg ins, #punhelp samp ins { + text-decoration: none; + } + +.pun div.postmsg h5, #punhelp h5 { + font-size: 1.1em; + font-weight: bold; + padding: 0.75em 0 0 0; + } + + +/***************************************************************** +3. COMMON STYLES +*****************************************************************/ + +/* Page Layout +----------------------------------------------------------------*/ + +.pun { + margin: 12px 20px + } + +#punredirect, #punmaint, #puninstall, #pundb_update { + margin: 50px 20% 12px 20% + } + + +/* Vertical Element Spacing +----------------------------------------------------------------*/ + +#brdheader { + margin: 0 0 12px 0; + } + +#announce, #brdstats { + margin: 12px 0 12px 0; + } + +.pun .blocktable, .pun .block, .pun .blockform, .pun .block2col, #postreview { + margin-bottom: 12px + } + +#punindex .blocktable, .pun .blockpost { + margin-bottom: 6px + } + +#postreview .blockpost { + margin-bottom: -1px; + } + +.pun .block2col .blockform, .pun .block2col .block { + margin-bottom: 0px + } + +.pun .linkst, .pun .linksb { + margin-top: -12px + } + +.pun .postlinksb { + margin-top: -6px + } + + +/* External Borders +----------------------------------------------------------------*/ + +.pun .box { + border-style: solid; + border-width: 1px; + } + +#brdheader .box { + border-top-width: 4px; + } + +/* Default Internal Spacing +----------------------------------------------------------------*/ + +.pun .block .inbox, .pun .blockmenu .inbox { + padding: 3px 6px + } + +/***************************************************************** +4. COMMON BOARD ELEMENTS +*****************************************************************/ + +/* Board Header +----------------------------------------------------------------*/ + +#brdtitle h1 { + font-size: 1.454em; + font-weight: bold; + line-height: 1em; + padding: 3px 0 0 0; + } + +#brddesc { + padding: 3px 0; + } + +#brddesc * { + padding-top: 0; + padding-bottom: 0; + } + +#brdmenu li { + display: inline; + margin-right: 12px; + } + +#brdmenu a:link, #brdmenu a:visited { + text-decoration: none + } + +#brdmenu a:hover, #brdmenu a:active { + text-decoration: underline + } + +#brdwelcome .conl { + float: left; + } + +#brdwelcome .conr { + float: right; + text-align: right; + } + +/* Breadcrumbs and Post Links +----------------------------------------------------------------*/ + +.pun .linkst { + padding: 8px 6px 3px 6px + } + +.pun .linksb, .pun .postlinksb { + padding: 3px 6px 8px 6px + } + +.pun .crumbs { + clear: both; + width: 100%; + overflow: hidden; + } + +.pun .crumbs li { + display: inline; + white-space: nowrap; + font-weight: bold; + } + +.pun .pagelink { + float: left; + white-space: nowrap; + } + +.pun .postlink { + font-weight: bold; + white-space: nowrap; + } + +.pun .postlink, .pun .modbuttons { + float: right; + text-align: right; + } + +.pun .modbuttons { + padding: 1px 0; + white-space: nowrap; + } + +.pun .modbuttons input { + margin-left: 6px; + } + +.pun .postlink a:link, .pun .postlink a:visited { + text-decoration: none + } + +.pun .postlink a:hover, .pun .postlink a:active { + text-decoration: underline; + } + + +/* Board Footer +----------------------------------------------------------------*/ + +#brdfooter .conl { + float: left; + } + +#brdfooter .conr { + float: right; + text-align: right; + } + +#brdfooter #modcontrols { + border-bottom-style: solid; + border-bottom-width: 1px; + text-align: center; + } + +#brdfooter #modcontrols dd { + display: inline; + margin:0 6px; + } + + +/* Board Stats +----------------------------------------------------------------*/ + +#brdstats .conl { + float: left; + } + +#brdstats .conr { + float: right; + text-align: right; + } + +#onlinelist dd, #onlinelist dt { + display: inline; + } + + +/***************************************************************** +5. MAIN TABLES +*****************************************************************/ + +.pun table { + width: 100%; + border-collapse: collapse; + border-spacing: 0; + empty-cells: show; + } + +.pun .blocktable table { + table-layout: fixed; + } + +.pun td, .pun th { + padding: 4px 6px; + line-height: 1.273em; + text-align: left; + font-weight: normal; + } + +.pun td { + border-style: solid none none solid; + border-width: 1px; + } + +.pun .tcl { + border-left: 0; + width: auto; + } + +.pun .tc2, .pun .tc3, .pun .tcmod { + width: 10%; + text-align: center; + padding: 4px 0; + } + +.pun .tcr { + width: 30%; + } + +.pun .tcl h3 { + font-size: 1.091em; + font-weight: bold; + } + +.pun .tcl h3 span.newtext { + font-size: 0.917em; + } + +.pun .tcl span.newtext, .pun .tcl span.pagestext { + white-space: nowrap; + font-weight: normal; + } + +.pun td span.byuser { + white-space: nowrap; + } + +.pun .tcl p { + padding: 5px 0 0 0 + } + +#punsearch #vf .tc2 { + width: 18%; + text-align: left; + padding: 4px 6px; + } + +#users1 .tcr { + width: 25% + } + +#users1 .tc2 { + width: 25%; + text-align: left; + padding: 4px 6px; + } + +#debug .tcl { + width: 10% + } + +#debug .tcr { + width: 90%; + white-space: normal + } + +#punindex .tcr .byuser { + display: block + } + +.pun .blocktable .tclcon { + padding: 0 11px 0 12px; + overflow: hidden; + height: 1%; + min-height: 1px; + position: relative; + } + +.pun .blocktable .tclcon div { + width: 100%; + overflow: hidden; + } + +.pun .icon { + border-width: 7px; + border-style: solid; + height: 0; + width: 0; + overflow: hidden; + float: left; + } + +.pun .icon div { + position: absolute; + left: -9999em; + text-indent: -9999em; + height: 0; + } + +.pun .iposted .ipost { + position: absolute; + left: 0; + font-weight: bold; + width: 8px; + padding-left: 4px; + text-align: center; + top: 0; + } + +/***************************************************************** +6. MAIN FORMS +*****************************************************************/ + +.pun .blockform form, .pun .fakeform { + PADDING: 20px 20px 15px 20px + } + +.pun .forminfo { + margin-bottom: 12px; + padding: 9px 10px; + border-style: solid; + border-width: 1px; + } + +.pun .forminfo h3 { + font-weight: bold; + } + +.pun .inform { + padding-bottom: 12px + } + +.pun fieldset { + padding: 0px 12px 0px 12px; + border-style: solid; + border-width: 1px + } + +.pun legend { + padding: 0px 6px + } + +.pun .infldset { + padding: 9px 0px 12px 0 + } + +.pun label { + display: block; + padding: 3px 0 + } + +.pun label.conl { + float: left; + overflow: visible; + margin-right: 10px + } + +.pun select { + padding-top: 1px; + padding-bottom: 1px; + } + +.pun fieldset .rbox { + } + +.pun fieldset .rbox br { + display: none; + } + +.pun fieldset .rbox label { + padding: 3px 0 3px 25px; + position: relative; + vertical-align: middle; + } + +.pun fieldset .rbox input { + margin: 0 9px 0 -25px; + padding: 0; + width: 16px; + position: relative; + vertical-align: middle; + } + +.pun .txtarea { + width: 75% + } + +.pun .txtarea textarea, .pun input.longinput { + width: 100% + } + +.pun .bblinks { + padding-bottom: 10px; + padding-left: 4px + } + +.pun .bblinks li { + display: inline; + padding-right: 20px + } + +.pun .blockform .buttons { + padding-left: 12px; + } + +.pun .blockform .buttons input { + margin-right: 8px; + } + +#posterror ul { + list-style: square; + padding: 3px 0 3px 24px; + } + +.pun .deletemsg { + border-style: solid; + border-width: 1px; + padding: 6px 15px; + } + +.pun p.actions span { + margin-right: 12px; + } + +/***************************************************************** +7. PROFILES AND ADMIN +*****************************************************************/ + +.pun .block2col { + padding-bottom: 1px + } + +.pun .block2col .blockform, .pun .block2col .block { + margin-left: 17em + } + +.pun .blockmenu { + float:left; + width: 16em + } + +.pun .blockmenu li { + padding: 3px 0; + font-weight: bold; + } + +.pun .blockmenu a:link, .pun .blockmenu a:visited { + text-decoration: none + } + +.pun .blockmenu a:hover, .pun .blockmenu a:active { + text-decoration: underline + } + +#viewprofile dl { + float: left; + width: 100%; + overflow: hidden + } + +#viewprofile dd { + margin-left: 14em; + padding: 3px; + } + +#viewprofile dt { + float: left; + width: 13em; + margin: 3px 0; + } + +#profileavatar img { + float: right; + margin-left: 1em + } + +/***************************************************************** +8. MAIN POSTS +*****************************************************************/ + +.pun .blockpost h2 a:link, .pun .blockpost h2 a:visited { + text-decoration: none; + } + +.pun .blockpost h2 a:hover, .pun .blockpost h2 a:active { + text-decoration: underline; + } + +.pun .blockpost h2 .conr { + float: right; + text-align: right; + } + +#punsearch .blockpost h2 span { + white-space: nowrap; + } + +.pun .blockpost .box { + overflow: hidden; + } + +.pun .postleft, .pun .postfootleft { + float:left; + width: 18em; + position: relative; + overflow: hidden; + } + +.pun .postleft dl { + padding: 0.75em 6px; + } + +.pun .postleft .usercontacts, .pun .postleft .icon { + margin-top: 6px + } + +.pun .postleft .postavatar, .pun .postleft .usertitle { + margin-bottom: 6px; + display: block; + } + +.pun .blockpost dt { + font-size: 1.091em; + font-weight: bold; + } + +.pun .blockpost dt a:link, .pun .blockpost dt a:visited { + text-decoration: none; + } + +.pun .blockpost dt a:hover, .pun .blockpost dt a:active { + text-decoration: underline; + } + +.pun .postright, .pun .postfootright { + border-left-width: 18em; + border-left-style: solid + } + +#postpreview .postright { + border-left: 0 + } + +.pun .postright { + padding: 0 6px; + } + +.pun .postfootright, .pun .multidelete { + text-align: right + } + +.pun .postmsg { + width:98%; + overflow: hidden; + padding-bottom: 6px; + } + +.pun .postfootright ul, .pun .postfootright div, .pun .postfootright p, +.pun .postfootleft p { + padding: 6px 6px 6px 6px; + } + +.pun .postfootright li { + display: inline; + margin-left: 12px; + } + +.pun .postfootright a:link, .pun .postfootright a:visited { + text-decoration: none + } + +.pun .postfootright a:hover, .pun .postfootright a:active { + text-decoration: underline + } + +.pun .codebox { + border-style: solid; + border-width: 1px; + margin: 0.75em 1em; + padding: 0; + } + +.pun .quotebox { + border-style: solid; + border-width: 1px; + margin: 0.75em 1em; + padding: 0 0.75em; + } + +.pun .quotebox cite { + display: block; + padding: 0.75em 0 0 0; + } + +.pun .quotebox blockquote { + width: 100%; + overflow: hidden + } + +.pun .codebox pre { + overflow: auto; + width: 100%; + overflow-y:hidden + } + +* html .pun .codebox pre { + padding-bottom: 10px; + } + +*+html .pun .codebox pre { + padding-bottom: 10px + } + +.pun .codebox pre code { + display: block; + padding: 0.75em; + } + +.pun .codebox pre.vscroll { + height: 32em; + overflow: auto; + overflow-y: auto + } + +.pun .postmsg img { + vertical-align: bottom; + } + +.pun .postsignature hr { + margin-left: 0px; + width: 200px; + text-align: left; + height: 1px; + border:none + } + +.pun .postmsg .postimg img { + max-width: 98%; + vertical-align: middle; +} + +.pun .postmsg .postimg a:link img, .pun .postmsg .postimg a:visited img { + border-style: solid; + border-width: 2px; +} + +.pun .blockpost label { + padding: 3px 6px; + border-style: solid; + border-width: 1px; + vertical-align: middle; + display: inline-block; + } + +.pun .blockpost label * { + vertical-align: middle; + margin: 0; + padding: 0; + } + +/****************************************************************/ +/* 9. HELP FILES AND MISC. */ +/****************************************************************/ + +#punhelp h2 { + margin-top: 12px + } + +#punhelp div.box { + padding: 10px + } + +#debugtime { + margin-top: -12px; + text-align: center; + } + +/***************************************************************** +COLOUR SCHEME +*****************************************************************/ + +/* Background / Text +----------------------------------------------------------------*/ + +body { + background: #fff; + color: #333 + } + +.pun { + color: #333 + } + +.pun .box, #adminconsole fieldset th { + background-color: #f1f1f1 + } + +.pun td.tc2, .pun td.tc3, .pun td.tcmod, #postpreview, #viewprofile dd, .pun .forminfo, +#brdfooter #modcontrols, #adminconsole fieldset td, .pun .blockmenu .box, #adstats dd { + background-color: #dedfdf + } + +.pun h2, #brdmenu { + background-color: #b84623; + color: #fff + } + +.pun th { + background-color: #d1d1d1 + } + +.pun legend { + color: #822100 + } + +.pun .blockmenu li.isactive a, #posterror li strong { + color: #333 + } + +.pun .usercontent * { + background: transparent; + color: #333 + } + +/* Posts +----------------------------------------------------------------*/ + +.pun .blockpost .box, .pun .postright, .pun .postfootright, .pun .deletemsg { + background-color: #dedfdf + } + +.pun .postright, .pun .postfootright { + border-left-color: #f1f1f1 + } + +.pun .postleft, .pun .postfootleft, .pun .blockpost label, .pun .codebox, .pun .quotebox { + background-color: #f1f1f1 + } + +#punhelp .codebox, #punhelp .quotebox { + background-color: #f9f9f9; + } + +.pun .blockpost h2 { + background-color: #d25028 + } + +.pun .blockpost h2 span.conr { + color: #fccfc1 + } + +.pun .postmsg ins, #punhelp samp ins { + background-color: #ff0; + } + +.pun hr { + background-color: #333; + color: #333 + } + +/* Borders +----------------------------------------------------------------*/ + +.pun .box { + border-color: #b84623 + } + +.pun td, #brdfooter #modcontrols { + border-color: #e1c3c3 + } + +.pun th, .pun fieldset { + border-color: #d1d1d1 + } + +#adminconsole td, #adminconsole th { + border-color: #f1f1f1 + } + +.pun .quotebox, .pun .codebox, .pun .forminfo, +.pun .blockpost label, .pun .deletemsg { + border-color: #aca899 #fff #fff #aca899 + } + +/* Links +----------------------------------------------------------------*/ + +.pun a:link, .pun a:visited { + color: #822100 + } + +.pun a:hover, .pun a:active, .pun a:focus { + color: #ca3300 + } + +.pun .postmsg .postimg a:link img, .pun .postmsg .postimg a:visited img { + border-color: #822100; +} + +.pun .postmsg .postimg a:hover img, .pun .postmsg .postimg a:active img, .pun .postmsg .postimg a:focus img { + border-color: #ca3300; +} + +.pun h2 a:link, .pun h2 a:visited, +#brdmenu a:link, #brdmenu a:visited { + color: #fff + } + +.pun h2 a:hover, .pun h2 a:active, +#brdmenu a:hover, #brdmenu a:active { + color: #fff + } + +.pun .postreport a:link, .pun .postreport a:visited, +.pun .iclosed td.tcl a:link, .pun .iclosed td.tcl a:visited { + color: #888 + } + +.pun .postreport a:hover, .pun .postreport a:active, +.pun .iclosed td.tcl a:hover, .pun .iclosed td.tcl a:active { + color: #aaa + } + +.pun .maintenancelink a:link, .pun .maintenancelink a:visited { + color: #b42000 + } + +.pun .maintenancelink a:hover, .pun .maintenancelink a:active { + color: #b42000 + } + +/* Status Indicators +----------------------------------------------------------------*/ + +.pun .icon { + border-color: #e6e6e6 #dedede #dadada #e2e2e2 + } + +.pun .iredirect .icon { + border-color: #f1f1f1 #f1f1f1 #f1f1f1 #f1f1f1 + } + +.pun .inew .icon { + border-color: #c23000 #af2c00 #992600 #ac2b00 + } diff --git a/style/Technetium.css b/style/Technetium.css new file mode 100644 index 0000000..6afd693 --- /dev/null +++ b/style/Technetium.css @@ -0,0 +1,1335 @@ +/***************************************************************** +Technitium theme CSS + +Yes, it is valid CSS 3, but unfortunately border-radius doesn't seem to work correctly in my Firefox version so I have to give it the moz versions, which break the validator. Sorry. +*****************************************************************/ + +/***************************************************************** +1. INITIAL SETTINGS +*****************************************************************/ + +/* Limited Reset +----------------------------------------------------------------*/ + +.pun table, .pun div, .pun form, .pun p, .pun h1, .pun h2, .pun h3, +.pun h4, .pun h5, .pun pre, .pun blockquote, .pun ul, .pun ol, .pun li, .pun dl, +.pun dt, .pun dd, .pun th, .pun td, .pun fieldset, .pun img, .pun abbr, .pun cite { + margin: 0; + padding: 0; + border: 0; + } + +.pun ul, .pun ol { + list-style: none + } + + +/* Structural Settings +----------------------------------------------------------------*/ + +body { + line-height: 1.9em; +} + +.pun { + width: 95%; + margin: 0 auto; + } + +.pun .clearer, .pun .nosize { + height: 0; + width: 0; + line-height: 0; + font-size: 0; + overflow: hidden + } + +.pun .clearer, .pun .clearb { + clear: both + } + +.pun .nosize { + position: absolute; + left: -9999em; + text-indent: -9999em; + width: 0; + } + +* html .inbox, * html .inform, * html .pun, * html .tclcon, * html .codebox { + height: 1px + } + +.pun, .pun .inbox, .pun .inform, .pun .tclcon, .pun .codebox { + min-height: 1px + } + + +/* Hidden Elements +----------------------------------------------------------------*/ + +#brdfooter h2, #brdstats h2, #brdstats .conl dt, #brdstats .conr dt, +#modcontrols dt, #searchlinks dt, div.postright h3 { + position: absolute; + display: block; + overflow: hidden; + width: 0; + left: -9999em; + text-indent: -9999em; + } + +/***************************************************************** +2. TEXT & CONTENT +*****************************************************************/ + +/* Text Defaults +----------------------------------------------------------------*/ + +.pun { + font: 10pt Georgia, Times, "Times New Roman", serif + } + +.pun table, .pun td, .pun th, .pun input, .pun select, .pun optgroup, .pun textarea, .pun samp { + font-size: 1em; + font-family: Georgia, Times, "Times New Roman", serif; + } + +.pun pre, .pun code { + font-size: 1.182em; + font-family: consolas, monaco, "bitstream vera sans mono", "courier new", courier, monospace + } + +.pun pre code { + font-size: 1em; + } + +.pun strong { + font-weight: bold; + } + +.pun em { + font-style: italic; + } + +#vf td { + font-size: 1.1em; + } + + +/* Content Defaults +----------------------------------------------------------------*/ + +.pun p, .pun ul, .pun ol, .pun dl { + font-size: 1em; + padding: 3px 0; + } + +.pun h2 { + font-size: 1.5em; + font-weight: normal; + padding: 4px 6px; + padding: 6px; + -moz-border-radius-topleft: 0.3em; + -moz-border-radius-topright: 0.3em; + -webkit-border-top-left-radius: 0.3em; + -webkit-border-top-right-radius: 0.3em; + } + +.pun h2 #brdmenu { + font-size: 1.1em; + } + +.pun .blockpost h2 { + font-size: 1.0em; + padding: 8px; + } + +.pun h3 { + font-size: 1.091em; + padding: 3px 0; + } + +.pun table p, .pun table h3 { + padding: 0; + } + +.pun span.warntext, .pun p.warntext { + font-weight: bold + } + +.pun .postleft dl dt { + font-size: 1.4em; + } + +/* User Content (Announcements, Rules, Posts) +----------------------------------------------------------------*/ + +.pun .usercontent p, .pun .postmsg p { + padding: 0.5em 0; + line-height: 1.6em; + } + +.pun .usercontent ul, .pun .postmsg ul { + padding: 0.75em 1em 0.75em 2.5em; + list-style: disc + } + +.pun .usercontent ol, .pun .postmsg ol { + padding: 0.75em 1em 0.75em 2.5em; + list-style: decimal + } + +.pun .usercontent ol.alpha, .pun .postmsg ol.alpha { + list-style: lower-alpha + } + +.pun .usercontent li ol, .pun .usercontent li ul, .pun .postmsg li ol, .pun .postmsg li ul { + padding: 0.25em 1em 0.75em 2.5em + } + +.pun .usercontent li p, .pun .postmsg li p { + padding: 0 + } + +.pun .usercontent h1 { + font-size: 1.4em; + font-weight: bold; + padding: 0.75em 0 0 0 + } + +.pun .usercontent h2 { + font-size: 1.2em; + font-weight: bold; + padding: 0.75em 0 0 0 + } + +.pun .usercontent h3 { + font-size: 1.1em; + font-weight: bold; + padding: 0.75em 0 0 0 + } + +.pun .usercontent h4, .pun .usercontent h5, .pun .usercontent h6 { + font-size: 1em; + font-weight: bold; + padding: 0.75em 0 0 0 + } + +.pun .quotebox cite { + font-weight: bold; + font-style: normal; + padding: 0.75em 0.75em 0 0.75em + } + +.pun span.bbu { + text-decoration: underline + } + +.pun span.bbs, .pun del { + text-decoration: line-through; + } + +.pun .postmsg ins, #punhelp samp ins { + text-decoration: none; + } + +.pun div.postmsg h5, #punhelp h5 { + font-size: 1.1em; + font-weight: bold; + padding: 0.75em 0 0 0; + } + +/***************************************************************** +3. COMMON STYLES +*****************************************************************/ + +/* Page Layout +----------------------------------------------------------------*/ + +.pun { + margin: 12px 20px + } + +#punredirect, #punmaint, #puninstall, #pundb_update { + margin: 50px 20% 12px 20%; + width: auto; + } + + +/* Vertical Element Spacing +----------------------------------------------------------------*/ + +#brdheader { + margin: 0 0 12px 0; + } + +#announce, #brdstats { + margin: 12px 0 12px 0; + } + +.pun .blocktable, .pun .block, .pun .blockform, .pun .block2col, #postreview { + margin-bottom: 12px + } + +#punindex .blocktable, .pun .blockpost { + margin-bottom: 6px + } + +#postreview .box { + margin-bottom: 3px; + } + +.pun .block2col .blockform, .pun .block2col .block { + margin-bottom: 0px + } + +.pun .linkst, .pun .linksb { + margin-top: -12px + } + +.pun .postlinksb { + margin-top: -6px + } + + +/* External Borders +----------------------------------------------------------------*/ + +.pun .box { + border-style: solid; + border-width: 1px; + } + + +.pun h2 { + border-width: 1px; + border-style: solid; + border-bottom: none; +} + + +/* Default Internal Spacing +----------------------------------------------------------------*/ + +.pun .block .inbox, .pun .blockmenu .inbox { + padding: 3px 6px + } + +/***************************************************************** +4. COMMON BOARD ELEMENTS +*****************************************************************/ + +/* Board Header +----------------------------------------------------------------*/ + +#brdtitle h1 { + font-size: 1.5em; + line-height: 1.1em; + padding: 3px 0 0 0; + } + +#brdmenu { + font-size:1.2em; + } + +#brddesc { + padding: 3px 0; + } + +#brddesc * { + padding-top: 0; + padding-bottom: 0; + } + + +#brdmenu li { + display: inline; + margin-right: 10px; + margin-top: 12px; + margin-bottom: 12px; + } + + +#brdmenu a:link, #brdmenu a:visited { + text-decoration: none; + text-shadow: #FFF 1px -1px 0.4em; + padding: 0.2em; + } + +#brdwelcome .conl { + float: left; + white-space: nowrap; + } + +#brdwelcome li { + float:left; + margin-right:8px; + white-space:nowrap; +} + +#brdwelcome .conl li strong:after { + content: '.' + } + +#brdwelcome .conr { + float: right; + text-align: right; + } + +#brdwelcome .conr li { + float: right; + text-align: right; + } + +/* Breadcrumbs and Post Links +----------------------------------------------------------------*/ + +.pun .linkst { + padding: 8px 6px 3px 6px + } + +.pun .linksb, .pun .postlinksb { + padding: 3px 6px 8px 6px + } + +.pun .crumbs { + clear: both; + width: 100%; + overflow: hidden; + } + +.pun .crumbs li { + display: inline; + white-space: nowrap; + font-weight: bold; + } + +.pun .linkst .crumbs { + font-size: 1.3em; + } + +.pun .pagelink { + float: left; + display: block; + white-space: normal; + } + +.pun .postlink { + font-size: 1.1em; + font-weight: bold; + white-space: wrap; + text-decoration: none; + } + +.pun .linkst .postlink { + position: relative; + margin-top: -0.2em; + margin-bottom: 0.5em; + } + +.pun .linksb .postlink, .pun .postlinksb .postlink { + position: relative; + margin-top: 0.5em; + margin-bottom: -0.5em; + } + +.pun .postlink, .pun .modbuttons { + float: right; + text-align: right; + } + +.pun .modbuttons { + padding: 1px 0; + white-space: nowrap; + } + +.pun .modbuttons input { + margin-left: 6px; + } + + +/* Board Footer +----------------------------------------------------------------*/ + +#brdfooter #modcontrols { + border-bottom-style: solid; + border-bottom-width: 1px; + text-align: center; + } + +#brdfooter #modcontrols dd { + display: inline; + margin-right: 10px; + } + +#brdfooter .conl { + float: left; + } + +#brdfooter .conr { + float: right; + text-align: right; + } + +#brdfooter #feedlinks span { + background:url("Technetium/feed.png") no-repeat scroll left center transparent; + padding-left:18px; + display: inline; +} + + +/* Board Stats +----------------------------------------------------------------*/ + +#brdstats .conl { + float: left; + } + +#brdstats .conr { + float: right; + text-align: right; + } + +#onlinelist dd, #onlinelist dt { + display: inline; + } + + +/***************************************************************** +5. MAIN TABLES +*****************************************************************/ + +.pun table { + width: 100%; + border-collapse: collapse; + border-spacing: 0; + empty-cells: show; + } + +.pun .blocktable table { + table-layout: fixed; + } + +.pun td, .pun th { + padding: 4px 6px; + line-height: 1.4em; + text-align: left; + font-weight: normal; + } + +.pun td { + border-style: solid none none solid; + border-width: 1px; + } + +.pun .tcl { + border-left: 0; + width: auto; + } + +.pun .tc2, .pun .tc3, .pun .tcmod { + width: 10%; + text-align: center; + padding: 4px 0; + } + +.pun .tcr { + width: 30%; + } + +.pun .tcl h3 { + font-size: 1.3em; + font-weight: bold; + } + +.pun .tcl span.newtext, .pun .tcl span.pagestext { + white-space: nowrap + } + +.pun .tcl p { + padding: 5px 0 0 0 + } + +#punsearch #vf .tc2 { + width: 18%; + text-align: left; + padding: 4px 6px; + } + +#users1 .tcr { + width: 25% + } + +#users1 .tc2 { + width: 25%; + text-align: left; + padding: 4px 6px; + } + +#debug .tcl { + width: 10% + } + +#debug .tcr { + width: 90%; + white-space: normal + } + +#punindex .tcr .byuser { + display: block + } + +.pun .blocktable .tclcon { + padding: 0 11px 0 12px; + overflow: hidden; + height: 1%; + min-height: 1px; + position: relative; + } + +.pun .blocktable .tclcon div { + width: 100%; + overflow: hidden; + } + +.pun .icon { + height: 24px; + width: 24px; + overflow: hidden; + float: left; + } + +.pun .icon div { + position: absolute; + left: -9999em; + text-indent: -9999em; + height: 0; + } + +.pun .iposted .ipost { + position: absolute; + left: 0; + font-weight: bold; + width: 8px; + padding-left: 4px; + text-align: center; + top: 0; + } + +.pun .stickytext { + display: none; + } + +.pun .movedtext { + display: none; +} + +.pun .closedtext { + font-weight: bold; + } +/***************************************************************** +6. MAIN FORMS +*****************************************************************/ + + +.pun .forminfo { + margin-bottom: 12px; + padding: 9px 10px; + border-style: solid; + border-width: 1px; + } + +.pun .forminfo h3 { + font-weight: bold; + } + + + +.pun .inform { + padding: 0 18px; +} + +.pun fieldset { + overflow: hidden; + width: 100%; + padding-bottom: 0.8em; +} + +.pun legend { + font-size: 1.2em; + font-weight: bold; + margin-left: -7px; + padding: 10px 19px 7px 19px; +} + +.pun div[class*="inform"] legend { + margin-left: 0; +} + +.pun .infldset { + border-style: solid; + border-width: 1px; + display: inline-block; + overflow: hidden; + padding: 12px 18px; +} + +.pun div[class*="infldset"] { + display: block; +} + +#punregister #rules .infldset { + padding: 5px 18px; +} + +.pun fieldset p { + clear: both; + padding: 0 0 7px 0; + width: 100%; +} + +.pun fieldset .usercontent p { + padding: 7px 0; +} + +.pun fieldset label { + clear: both; + display: block; + padding: 0 0 7px 0; +} + + +.pun label { + display: block; + padding: 3px 0 + } + +.pun label.conl { + float: left; + overflow: visible; + margin-right: 10px + } + +.pun select { + padding-top: 1px; + padding-bottom: 1px; + } + +.pun fieldset .rbox { + } + +.pun fieldset .rbox br { + display: none; + } + +.pun fieldset .rbox label { + padding: 3px 0 3px 25px; + position: relative; + vertical-align: middle; + } + +.pun fieldset .rbox input { + margin: 0 9px 0 -25px; + padding: 0; + width: 16px; + position: relative; + vertical-align: middle; + } + +.pun .txtarea { + width: 90% + } + +.pun .txtarea textarea, .pun input.longinput { + width: 100% + } + +.pun .bblinks { + padding-bottom: 10px; + padding-left: 4px + } + +.pun .bblinks li { + display: inline; + padding-right: 20px + } + +.pun .blockform .buttons { + padding-left: 18px; + padding-bottom: 5px; + } + +.pun .blockform .buttons input { + margin-right: 8px; + } + +#posterror ul { + list-style: square; + padding: 3px 0 3px 24px; + } + +.pun .deletemsg { + border-style: solid; + border-width: 1px; + padding: 6px 15px; + } + + +/***************************************************************** +7. PROFILES AND ADMIN +*****************************************************************/ + +.pun .block2col { + padding-bottom: 1px + } + +.pun .block2col .blockform, .pun .block2col .block { + margin-left: 14em + } + +.pun .blockmenu { + float:left; + width: 13em + } + +.pun .blockmenu li { + padding: 3px 0; + font-weight: bold; + } + +.pun .blockmenu a:link, .pun .blockmenu a:visited { + text-decoration: none + } + +.pun .blockmenu a:hover, .pun .blockmenu a:active { + text-decoration: underline + } + +#viewprofile dl { + float: left; + width: 100%; + overflow: hidden + } + +#viewprofile dd { + margin-left: 14em; + padding: 3px; + } + +#viewprofile dt { + float: left; + width: 13em; + margin: 3px 0; + } + +#profileavatar img { + float: right; + margin-left: 1em + } + +/***************************************************************** +8. MAIN POSTS +*****************************************************************/ + +.pun .blockpost h2 a:link, .pun .blockpost h2 a:visited { + text-decoration: none; + } + +.pun .blockpost h2 a:hover, .pun .blockpost h2 a:active { + text-decoration: underline; + } + +.pun .blockpost h2 .conr { + float: right; + text-align: right; + } + +#punsearch .blockpost h2 span { + white-space: nowrap; + } + +.pun .blockpost .box { + overflow: hidden; + } + +.pun .postleft, .pun .postfootleft { + float:left; + width: 18em; + overflow: hidden; + position: relative; + overflow: hidden; + } + +.pun .postleft dl { + padding: 0.5em 6px; + } + +.pun .postleft .usercontacts, .pun .postleft .icon { + margin-top: 6px + } + +.pun .postleft .postavatar, .pun .postleft .usertitle { + margin-bottom: 6px; + display: block; + } + +.pun .blockpost dt { + font-size: 1.091em; + font-weight: bold; + } + +.pun .blockpost dt a:link, .pun .blockpost dt a:visited { + text-decoration: none; + } + +.pun .blockpost dt a:hover, .pun .blockpost dt a:active { + text-decoration: underline; + } + +.pun .postright, .pun .postfootright { + border-left-width: 18em; + border-left-style: solid + } + +#postpreview .postright { + border-left: 0 + } + +.pun .postright { + padding: 0 6px; + } + +.pun .postfootright, .pun .multidelete { + text-align: right + } + +.pun .postmsg { + width:98%; + overflow: hidden; + padding-bottom: 6px; + } + +.pun .postfootright ul, .pun .postfootright div, .pun .postfootright p, +.pun .postfootleft p { + padding: 6px 6px 6px 6px; + } + +.pun .postfootright li { + display: inline; + } + +.pun .postfootright a:link, .pun .postfootright a:visited { + text-decoration: none + } + +.pun .postfootright a:hover, .pun .postfootright a:active { + text-decoration: underline + } + + +.pun .quotebox, .pun .codebox { + border-style: solid; + border-width: 2px; + border-left: 5px solid; + margin: 0.75em 1em; + padding: 0 0.75em; + } + +.pun .quotebox cite { + display: block; + padding: 0.75em 0 0 0; + } + +.pun .quotebox blockquote { + width: 100%; + overflow: hidden + } + +.pun .codebox pre { + overflow: auto; + width: 100%; + overflow-y:hidden + } + +* html .pun .codebox pre { + padding-bottom: 10px; + } + +*+html .pun .codebox pre { + padding-bottom: 10px + } + +.pun .codebox pre code { + display: block; + padding: 0.75em; + } + +.pun .codebox pre.vscroll { + height: 32em; + overflow: auto; + overflow-y: auto + } + +.pun .postmsg img.postimg, .pun .postmsg a img.postimg { + max-width: 100%; + vertical-align: middle; + } + +.pun .postmsg img { + vertical-align: bottom; + } + +.pun .postsignature hr { + margin-left: 0px; + width: 200px; + text-align: left; + height: 1px; + border:none + } + +.pun .blockpost label { + padding: 3px 6px; + border-style: solid; + border-width: 1px; + vertical-align: middle; + display: inline-block; + } + +.pun .blockpost label * { + vertical-align: middle; + margin: 0; + padding: 0; + } + + +/****************************************************************/ +/* 9. HELP FILES AND MISC. */ +/****************************************************************/ + +#punhelp h2 { + margin-top: 12px + } + +#punhelp div.box { + padding: 10px + } + +/***************************************************************** +COLOUR SCHEME +*****************************************************************/ + +/* Background / Text +----------------------------------------------------------------*/ + +body { + background: #fff url("Technetium/bg.png") repeat-x top; + color: #122434 + } + +.pun { + color: #122434 + } + +.pun .box, #adminconsole fieldset th { + background-color: #FBFCFD; + background-image: url("Technetium/light-shade.png"); + background-position: bottom; + background-repeat: repeat-x; + } + +.pun td.tc2, .pun td.tc3, .pun td.tcmod, #postpreview, #viewprofile dd, .pun .forminfo, +#brdfooter #modcontrols, #adminconsole fieldset td, .pun .blockmenu .box, #adstats dd { + background-color: #F4F9FD; + background-image: url("Technetium/light-shade.png"); + background-repeat: repeat-x; + background-position: bottom; + } + +.pun h2, #brdmenu { + background-color: #C5D8EB; + color: #122434; + background-image: url("Technetium/dark-shade.png"); + background-repeat: repeat-x; + background-position: top; + } + +.pun h2 { + background-color: #C5D8EB; + background-image: url("Technetium/inv-shade.png"); + background-repeat: repeat-x; + color: #122434; + text-shadow: #FFF 1px -1px 0.7em; + } + +.pun #announce h2 { + display: none; + } + +.box #announce-block { + background-color: #FDFCE3; +} + +.pun th { + background-color: #EFF3F8; + background-image: url("Technetium/light-shade.png"); + background-repeat: repeat-x; + } + +.pun td { + background-image: url("Technetium/light-shade.png"); + background-color: #FBFCFD; + background-position: bottom; + background-repeat: repeat-x; + } + +.pun .isticky td { + background-color: #E4EBF1; + } + +.pun .iclosed td { + background-color: #ECEEF0 + } + +.pun .iclosed.isticky td { + background-color: #CDD6E0; + } + +.pun legend { + color: #122434 + } + +.pun .blockmenu li.isactive a, #posterror li strong { + color: #333 + } + +.pun .usercontent * { + background: transparent; + color: #333 + } + +#adminmenu .box { + background: #FBFCFD; + } + +.pun .postlink a:link, .pun .postlink a:visited, .pun .postlink a:active { + background-color:#F0F5FA; + background-image:url(Technetium/inv-shade.png); + background-repeat:repeat-x; + border: 1px solid; + color:#2B3037; + text-shadow: #FFF 1px -1px 0.4em; + padding: 0.3em; + border-radius: 0.4em; + position: relative; + -moz-border-radius: 0.4em; + -webkit-border-top-left-radius: 0.4em; + -webkit-border-top-right-radius: 0.4em; + -webkit-border-bottom-left-radius: 0.4em; + -webkit-border-bottom-right-radius: 0.4em; + + } + +.pun .postlink a:hover { + background-color: #C0D6E9; + color: #000; + } + +#brdheader .box { + background-color:#F0F5FA; + background-image:url(Technetium/light-shade.png); + background-repeat:repeat-x; + background-position: top; + color:#122434; + border-radius: 0.4em; + -moz-border-radius: 0.4em; + -webkit-border-top-left-radius: 0.4em; + -webkit-border-top-right-radius: 0.4em; + -webkit-border-bottom-left-radius: 0.4em; + -webkit-border-bottom-right-radius: 0.4em; + } + +.pun #brdtitle { + background-color: #D1E1EF; + background-image: url("Technetium/inv-shade.png"); + background-repeat: repeat-x; + text-shadow: #FFF 1px -1px 0.4em; + } + + +.pun .infldset, #pundelete .deletemsg, #adintro .inbox, #adstats .inbox { + background: #FBFCFD url(Technetium/light-shade.png) bottom repeat-x; + border-color: #C0CCD8; +} + + +/* Posts +----------------------------------------------------------------*/ + +.pun .blockpost .box, .pun .postright, .pun .postfootright, .pun .deletemsg { + background-color: #F8FAFD; + } + +.pun .postright, .pun .postfootright { + border-left-color: #F0F5FA + } + +.pun .postleft, .pun .postfootleft, .pun .blockpost label, .pun .codebox, .pun .quotebox { + background-color: #F0F5FA + } + +#punhelp .codebox, #punhelp .quotebox { + background-color: #f9f9f9; + } + +.pun .blockpost h2 { + background-color: #F0F5FA; + } + +.pun .blockpost h2 span.conr { + color: #aabdcd + } + +.pun hr { + background-color: #333; + color: #333 + } + +.pun .quotebox { + background-color: #FAFCFE; + } + +.pun .postmsg ins, #punhelp samp ins { + background-color: #ff0; + } + +/* Borders +----------------------------------------------------------------*/ + +.pun .box, .pun h2, #brdfooter #modcontrols { + border-color: #A2B5CC; +} + +.blocktable #announce h2 { + border-color: #F6B620; +} + +.pun td { + border-color: #A2B5CC; + } + +.pun th, .pun fieldset { + border-color: #A2B5CC; + } + +#adminconsole td, #adminconsole th { + border-style:solid; + border-width:1px 0px !important; +} + +#adminconsole th { + border-width: 1px 0px 1px 1px !important; +} + +#adminconsole td { + border-width: 1px 1px 1px 1px !important; +} + +.pun .forminfo, .pun .blockpost label, .pun .deletemsg { + border-color: #aca899 #fff #fff #aca899; + } + +.pun .quotebox, .pun .codebox { + border-color: #BCD2E9; + } + +.pun .postlink a:link, .pun .postlink a:visited { + border-color: #C0D6E9 + } + + +/* Links +----------------------------------------------------------------*/ + +.pun a:link, .pun a:visited { + color: #1F537B; + text-decoration: none; + } + +.pun a:hover, .pun a:active, .pun a:focus { + color: #9E1D00 + } + +#brdmenu li a:active, #brdmenu li a:link, #brdmenu li a:visited { + color: #1F2E3D; + } + +#brdmenu li a:hover { + color: #000; + text-shadow: #8895A2 1px -1px 0.4em; + } + +#vf a { + font-weight: bold; + } + +.pun .postreport a:link, .pun .postreport a:visited, +.pun .iclosed td.tcl a:link, .pun .iclosed td.tcl a:visited { + color: #888 + } + +.pun .isticky.iclosed td.tcl a:link, .pun .isticky.iclosed td.tcl a:visited { + color: #475F6B !important; + } + +.pun .isticky.iclosed td.tcl a:hover { + color: #577382 !important; + } + + +.pun .postreport a:hover, .pun .postreport a:active, +.pun .iclosed td.tcl a:hover, .pun .iclosed td.tcl a:active { + color: #aaa + } + +.pun .maintenancelink a:link, .pun .maintenancelink a:visited { + color: #b42000 + } + +.pun .maintenancelink a:hover, .pun .maintenancelink a:active { + color: #b42000 + } + + +/* Status Indicators +----------------------------------------------------------------*/ + +.pun .icon { + background-image:url(Technetium/icon-nonew.png); + } + +.pun .iredirect .icon { + background-image:url(Technetium/icon-moved.png); + } + +.pun .inew .icon{ + background-image:url(Technetium/icon-new.png); + } + +.pun .iclosed .icon { + background-image:url(Technetium/icon-closed.png); + } + +.pun .isticky .icon { + background-image:url(Technetium/icon-nonew-sticky.png); + } + +.pun .isticky.inew .icon { + background-image:url(Technetium/icon-new-sticky.png); + } + +.pun .iclosed.isticky .icon { + background-image:url(Technetium/icon-closed-sticky.png); + } + +.pun .imoved .icon { + background-image:url(Technetium/icon-moved.png); + } diff --git a/style/Technetium/bg.png b/style/Technetium/bg.png new file mode 100644 index 0000000..fb5c156 Binary files /dev/null and b/style/Technetium/bg.png differ diff --git a/style/Technetium/dark-shade.png b/style/Technetium/dark-shade.png new file mode 100644 index 0000000..2f4a975 Binary files /dev/null and b/style/Technetium/dark-shade.png differ diff --git a/style/Technetium/darker-shade.png b/style/Technetium/darker-shade.png new file mode 100644 index 0000000..914eb26 Binary files /dev/null and b/style/Technetium/darker-shade.png differ diff --git a/style/Technetium/feed.png b/style/Technetium/feed.png new file mode 100644 index 0000000..d4cf8ce Binary files /dev/null and b/style/Technetium/feed.png differ diff --git a/style/Technetium/icon-closed-sticky.png b/style/Technetium/icon-closed-sticky.png new file mode 100644 index 0000000..cfa6e63 Binary files /dev/null and b/style/Technetium/icon-closed-sticky.png differ diff --git a/style/Technetium/icon-closed.png b/style/Technetium/icon-closed.png new file mode 100644 index 0000000..a260ac3 Binary files /dev/null and b/style/Technetium/icon-closed.png differ diff --git a/style/Technetium/icon-moved.png b/style/Technetium/icon-moved.png new file mode 100644 index 0000000..56a313b Binary files /dev/null and b/style/Technetium/icon-moved.png differ diff --git a/style/Technetium/icon-new-sticky.png b/style/Technetium/icon-new-sticky.png new file mode 100644 index 0000000..738d179 Binary files /dev/null and b/style/Technetium/icon-new-sticky.png differ diff --git a/style/Technetium/icon-new.png b/style/Technetium/icon-new.png new file mode 100644 index 0000000..95af1e8 Binary files /dev/null and b/style/Technetium/icon-new.png differ diff --git a/style/Technetium/icon-nonew-sticky.png b/style/Technetium/icon-nonew-sticky.png new file mode 100644 index 0000000..2440799 Binary files /dev/null and b/style/Technetium/icon-nonew-sticky.png differ diff --git a/style/Technetium/icon-nonew.png b/style/Technetium/icon-nonew.png new file mode 100644 index 0000000..e769387 Binary files /dev/null and b/style/Technetium/icon-nonew.png differ diff --git a/style/Technetium/index.html b/style/Technetium/index.html new file mode 100644 index 0000000..89337b2 --- /dev/null +++ b/style/Technetium/index.html @@ -0,0 +1 @@ +.. diff --git a/style/Technetium/inv-shade.png b/style/Technetium/inv-shade.png new file mode 100644 index 0000000..e2c80f2 Binary files /dev/null and b/style/Technetium/inv-shade.png differ diff --git a/style/Technetium/light-shade.png b/style/Technetium/light-shade.png new file mode 100644 index 0000000..b191465 Binary files /dev/null and b/style/Technetium/light-shade.png differ diff --git a/style/imports/base_admin.css b/style/imports/base_admin.css new file mode 100644 index 0000000..774c2ac --- /dev/null +++ b/style/imports/base_admin.css @@ -0,0 +1,47 @@ +#adminconsole .block2 {MARGIN-TOP: 12px} + +/*** Admin Main Content ***/ +* HTML #adstats DD {HEIGHT: 1%} +#adstats DD {MARGIN-LEFT: 14em; PADDING: 3px; MARGIN-BOTTOM: 5px; LINE-HEIGHT: 1.5em} +#adstats DT {FLOAT: left; WIDTH: 13em; PADDING: 3px; LINE-HEIGHT: 1.5em} +#adstats {PADDING: 15px 15px 5px 10px} +#adintro {PADDING: 5px} +#adintro P {PADDING: 10px} +#adstats DL {PADDING: 5px 0 10px 5px} + +#adminconsole FIELDSET TD {TEXT-ALIGN: left; PADDING: 4px; WHITE-SPACE: normal} +#adminconsole FIELDSET TH {TEXT-ALIGN: left; PADDING: 4px; WHITE-SPACE: normal} +#adminconsole FIELDSET TD SPAN, #adminconsole FIELDSET TH SPAN {DISPLAY: block; FONT-SIZE: 1em; FONT-WEIGHT: normal} +#adminconsole TH {WIDTH: 15em; FONT-WEIGHT: bold} +#adminconsole INPUT, #adminconsole SELECT, #adminconsole TEXTAREA {MARGIN-BOTTOM: 0; MARGIN-TOP: 0; FONT-WEIGHT: normal} +#adminconsole TABLE.aligntop TH, #adminconsole TABLE.aligntop TD {VERTICAL-ALIGN: top} +#adminconsole TABLE.aligntop TH {PADDING-TOP: 0.7em} +#adminconsole TD, #adminconsole TH {BORDER-STYLE: solid; BORDER-WIDTH: 3px 0 3px 0} +#adminconsole P {PADDING-BOTTOM: 6px} +#adminconsole .topspace {PADDING-TOP: 6px} +#adminconsole P.submittop, #adminconsole P.submitend {TEXT-ALIGN: center} +#adminconsole TH.hidehead {COLOR: #f1f1f1} +#adminconsole THEAD TH {PADDING-BOTTOM: 0} +#adminconsole P.linkactions {FONT-WEIGHT: bold; PADDING-LEFT: 5px} +#adminconsole TH INPUT, #adminconsole DIV.fsetsubmit {MARGIN-TOP: 6px} + +/*** Particular table settings ***/ +#categoryedit .tcl {WIDTH: 25%} +#censoring .tcl, #censoring .tc2, #ranks .tcl, #ranks .tc2 {WIDTH: 20%} +#edforum .tcl, #edforum .tc2 {WIDTH: 8%} +#edforum .tc2 {WIDTH: 6%} + +TABLE#forumperms TH, TABLE#forumperms TD {WHITE-SPACE: normal; WIDTH: auto; TEXT-ALIGN: center} +TABLE#forumperms .atcl {TEXT-ALIGN: left; WIDTH: 15em; WHITE-SPACE: nowrap} +#adminconsole TD.nodefault {BACKGROUND-COLOR: #D59B9B} + +/*** User/Ban Search Result Tables ***/ +#users2 TH, #bans1 TH {TEXT-ALIGN: left} +#users2 .tcl, #users2 .tc3, #users2 .tc5, #bans1 .tcl, #bans1 .tc3, #bans1 .tc5, #bans1 .tc6 {WIDTH: 15%; TEXT-ALIGN: left; PADDING: 4px 6px} +#users2 .tc2, #bans1 .tc2 {WIDTH: 22%; TEXT-ALIGN: left; PADDING: 4px 6px} +#users2 .tc4, #bans1 .tc4 {WIDTH: 8%; TEXT-ALIGN: center} +#users2 .tcr, #bans1 .tcr {WHITE-SPACE: nowrap} +#adminconsole #linkst, #adminconsole #linksb A {FONT-WEIGHT: bold} + +/*** Plugins ***/ +#exampleplugin .inbox {PADDING: 6px 6px 0px 6px} diff --git a/style/imports/index.html b/style/imports/index.html new file mode 100644 index 0000000..89337b2 --- /dev/null +++ b/style/imports/index.html @@ -0,0 +1 @@ +.. diff --git a/style/imports/minmax.js b/style/imports/minmax.js new file mode 100644 index 0000000..65fddca --- /dev/null +++ b/style/imports/minmax.js @@ -0,0 +1,84 @@ +// minmax.js - written by Andrew Clover +// Adapted for PunBB by Rickard Andersson and Paul Sullivan + +/*@cc_on +@if (@_win32 && @_jscript_version>4) + +var minmax_elements; + +function minmax_bind(el) { + var em, ms; + var st= el.style, cs= el.currentStyle; + + if (minmax_elements==window.undefined) { + if (!document.body || !document.body.currentStyle) return; + minmax_elements= new Array(); + window.attachEvent('onresize', minmax_delayout); + } + + if (cs['max-width']) + st['maxWidth']= cs['max-width']; + + ms= cs['maxWidth']; + if (ms && ms!='auto' && ms!='none' && ms!='0' && ms!='') { + st.minmaxWidth= cs.width; + minmax_elements[minmax_elements.length]= el; + minmax_delayout(); + } +} + +var minmax_delaying= false; +function minmax_delayout() { + if (minmax_delaying) return; + minmax_delaying= true; + window.setTimeout(minmax_layout, 0); +} + +function minmax_stopdelaying() { + minmax_delaying= false; +} + +function minmax_layout() { + window.setTimeout(minmax_stopdelaying, 100); + var i, el, st, cs, optimal, inrange; + for (i= minmax_elements.length; i-->0;) { + el= minmax_elements[i]; st= el.style; cs= el.currentStyle; + + st.width= st.minmaxWidth; optimal= el.offsetWidth; + inrange= true; + if (inrange && cs.minWidth && cs.minWidth!='0' && cs.minWidth!='auto' && cs.minWidth!='') { + st.width= cs.minWidth; + inrange= (el.offsetWidthoptimal); + } + if (inrange) st.width= st.minmaxWidth; + } +} + +var minmax_SCANDELAY= 500; + +function minmax_scan() { + var el; + for (var i= 0; i.. diff --git a/upload/admin_bans.php b/upload/admin_bans.php deleted file mode 100644 index 2583d38..0000000 --- a/upload/admin_bans.php +++ /dev/null @@ -1,526 +0,0 @@ -query('SELECT group_id, username, email FROM '.$db->prefix.'users WHERE id='.$user_id) or error('Unable to fetch user info', __FILE__, __LINE__, $db->error()); - if ($db->num_rows($result)) - list($group_id, $ban_user, $ban_email) = $db->fetch_row($result); - else - message($lang_admin_bans['No user ID message']); - } - else // Otherwise the username is in POST - { - $ban_user = pun_trim($_POST['new_ban_user']); - - if ($ban_user != '') - { - $result = $db->query('SELECT id, group_id, username, email FROM '.$db->prefix.'users WHERE username=\''.$db->escape($ban_user).'\' AND id>1') or error('Unable to fetch user info', __FILE__, __LINE__, $db->error()); - if ($db->num_rows($result)) - list($user_id, $group_id, $ban_user, $ban_email) = $db->fetch_row($result); - else - message($lang_admin_bans['No user message']); - } - } - - // Make sure we're not banning an admin - if (isset($group_id) && $group_id == PUN_ADMIN) - message(sprintf($lang_admin_bans['User is admin message'], pun_htmlspecialchars($ban_user))); - - // If we have a $user_id, we can try to find the last known IP of that user - if (isset($user_id)) - { - $result = $db->query('SELECT poster_ip FROM '.$db->prefix.'posts WHERE poster_id='.$user_id.' ORDER BY posted DESC LIMIT 1') or error('Unable to fetch post info', __FILE__, __LINE__, $db->error()); - $ban_ip = ($db->num_rows($result)) ? $db->result($result) : ''; - } - - $mode = 'add'; - } - else // We are editing a ban - { - $ban_id = intval($_GET['edit_ban']); - if ($ban_id < 1) - message($lang_common['Bad request']); - - $result = $db->query('SELECT username, ip, email, message, expire FROM '.$db->prefix.'bans WHERE id='.$ban_id) or error('Unable to fetch ban info', __FILE__, __LINE__, $db->error()); - if ($db->num_rows($result)) - list($ban_user, $ban_ip, $ban_email, $ban_message, $ban_expire) = $db->fetch_row($result); - else - message($lang_common['Bad request']); - - $ban_expire = ($ban_expire != '') ? date('Y-m-d', $ban_expire) : ''; - - $mode = 'edit'; - } - - $page_title = array(pun_htmlspecialchars($pun_config['o_board_title']), $lang_admin_common['Admin'], $lang_admin_common['Bans']); - $focus_element = array('bans2', 'ban_user'); - define('PUN_ACTIVE_PAGE', 'admin'); - require PUN_ROOT.'header.php'; - - generate_admin_menu('bans'); - -?> -
    -

    -
    -
    -
    - - -
    - -
    - - - - - - - - - - - - - -
    - - -
    - - '.$lang_admin_common['here'].'') ?> -
    - - -
    -

    -
    -
    -
    -
    -
    - -
    - - - - - - - - - -
    - - -
    - - -
    -
    -
    -
    -

    -
    -
    -
    -
    - - 7 || (!empty($octets[$c]) && !ctype_xdigit($octets[$c])) || intval($octets[$c], 16) > 65535) - message($lang_admin_bans['Invalid IP message']); - } - - $cur_address = implode(':', $octets); - $addresses[$i] = $cur_address; - } - else - { - $octets = explode('.', $addresses[$i]); - - for ($c = 0; $c < count($octets); ++$c) - { - $octets[$c] = (strlen($octets[$c]) > 1) ? ltrim($octets[$c], "0") : $octets[$c]; - - if ($c > 3 || preg_match('/[^0-9]/', $octets[$c]) || intval($octets[$c]) > 255) - message($lang_admin_bans['Invalid IP message']); - } - - $cur_address = implode('.', $octets); - $addresses[$i] = $cur_address; - } - } - - $ban_ip = implode(' ', $addresses); - } - - require PUN_ROOT.'include/email.php'; - if ($ban_email != '' && !is_valid_email($ban_email)) - { - if (!preg_match('/^[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,4})$/', $ban_email)) - message($lang_admin_bans['Invalid e-mail message']); - } - - if ($ban_expire != '' && $ban_expire != 'Never') - { - $ban_expire = strtotime($ban_expire); - - if ($ban_expire == -1 || $ban_expire <= time()) - message($lang_admin_bans['Invalid date message'].' '.$lang_admin_bans['Invalid date reasons']); - } - else - $ban_expire = 'NULL'; - - $ban_user = ($ban_user != '') ? '\''.$db->escape($ban_user).'\'' : 'NULL'; - $ban_ip = ($ban_ip != '') ? '\''.$db->escape($ban_ip).'\'' : 'NULL'; - $ban_email = ($ban_email != '') ? '\''.$db->escape($ban_email).'\'' : 'NULL'; - $ban_message = ($ban_message != '') ? '\''.$db->escape($ban_message).'\'' : 'NULL'; - - if ($_POST['mode'] == 'add') - $db->query('INSERT INTO '.$db->prefix.'bans (username, ip, email, message, expire, ban_creator) VALUES('.$ban_user.', '.$ban_ip.', '.$ban_email.', '.$ban_message.', '.$ban_expire.', '.$pun_user['id'].')') or error('Unable to add ban', __FILE__, __LINE__, $db->error()); - else - $db->query('UPDATE '.$db->prefix.'bans SET username='.$ban_user.', ip='.$ban_ip.', email='.$ban_email.', message='.$ban_message.', expire='.$ban_expire.' WHERE id='.intval($_POST['ban_id'])) or error('Unable to update ban', __FILE__, __LINE__, $db->error()); - - // Regenerate the bans cache - if (!defined('FORUM_CACHE_FUNCTIONS_LOADED')) - require PUN_ROOT.'include/cache.php'; - - generate_bans_cache(); - - if ($_POST['mode'] == 'edit') - redirect('admin_bans.php', $lang_admin_bans['Ban edited redirect']); - else - redirect('admin_bans.php', $lang_admin_bans['Ban added redirect']); -} - -// Remove a ban -else if (isset($_GET['del_ban'])) -{ - confirm_referrer('admin_bans.php'); - - $ban_id = intval($_GET['del_ban']); - if ($ban_id < 1) - message($lang_common['Bad request']); - - $db->query('DELETE FROM '.$db->prefix.'bans WHERE id='.$ban_id) or error('Unable to delete ban', __FILE__, __LINE__, $db->error()); - - // Regenerate the bans cache - if (!defined('FORUM_CACHE_FUNCTIONS_LOADED')) - require PUN_ROOT.'include/cache.php'; - - generate_bans_cache(); - - redirect('admin_bans.php', $lang_admin_bans['Ban removed redirect']); -} - -// Find bans -else if (isset($_GET['find_ban'])) -{ - $form = isset($_GET['form']) ? $_GET['form'] : array(); - - // trim() all elements in $form - $form = array_map('pun_trim', $form); - $conditions = $query_str = array(); - - $expire_after = isset($_GET['expire_after']) ? trim($_GET['expire_after']) : ''; - $expire_before = isset($_GET['expire_before']) ? trim($_GET['expire_before']) : ''; - $order_by = isset($_GET['order_by']) && in_array($_GET['order_by'], array('username', 'ip', 'email', 'expire')) ? $_GET['order_by'] : 'username'; - $direction = isset($_GET['direction']) && $_GET['direction'] == 'DESC' ? 'DESC' : 'ASC'; - - $query_str[] = 'order_by='.$order_by; - $query_str[] = 'direction='.$direction; - - // Try to convert date/time to timestamps - if ($expire_after != '') - { - $query_str[] = 'expire_after='.$expire_after; - - $expire_after = strtotime($expire_after); - if ($expire_after === false || $expire_after == -1) - message($lang_admin_bans['Invalid date message']); - - $conditions[] = 'expire>'.$expire_after; - } - if ($expire_before != '') - { - $query_str[] = 'expire_before='.$expire_before; - - $expire_before = strtotime($expire_before); - if ($expire_before === false || $expire_before == -1) - message($lang_admin_bans['Invalid date message']); - - $conditions[] = 'expire<'.$expire_before; - } - - $like_command = ($db_type == 'pgsql') ? 'ILIKE' : 'LIKE'; - while (list($key, $input) = @each($form)) - { - if ($input != '' && in_array($key, array('username', 'ip', 'email', 'message'))) - { - $conditions[] = 'b.'.$db->escape($key).' '.$like_command.' \''.$db->escape(str_replace('*', '%', $input)).'\''; - $query_str[] = 'form%5B'.$key.'%5D='.urlencode($input); - } - } - - // Fetch ban count - $result = $db->query('SELECT COUNT(id) FROM '.$db->prefix.'bans as b WHERE b.id>0'.(!empty($conditions) ? ' AND '.implode(' AND ', $conditions) : '')) or error('Unable to fetch ban list', __FILE__, __LINE__, $db->error()); - $num_bans = $db->result($result); - - // Determine the ban offset (based on $_GET['p']) - $num_pages = ceil($num_bans / 50); - - $p = (!isset($_GET['p']) || $_GET['p'] <= 1 || $_GET['p'] > $num_pages) ? 1 : intval($_GET['p']); - $start_from = 50 * ($p - 1); - - // Generate paging links - $paging_links = ''.$lang_common['Pages'].' '.paginate($num_pages, $p, 'admin_bans.php?find_ban=&'.implode('&', $query_str)); - - $page_title = array(pun_htmlspecialchars($pun_config['o_board_title']), $lang_admin_common['Admin'], $lang_admin_common['Bans'], $lang_admin_bans['Results head']); - define('PUN_ACTIVE_PAGE', 'admin'); - require PUN_ROOT.'header.php'; - -?> -
    -
    -
      -
    • -
    • » 
    • -
    • » 
    • -
    - -
    -
    -
    - - -
    -

    -
    -
    - - - - - - - - - - - - - -query('SELECT b.id, b.username, b.ip, b.email, b.message, b.expire, b.ban_creator, u.username AS ban_creator_username FROM '.$db->prefix.'bans AS b LEFT JOIN '.$db->prefix.'users AS u ON b.ban_creator=u.id WHERE b.id>0'.(!empty($conditions) ? ' AND '.implode(' AND ', $conditions) : '').' ORDER BY '.$db->escape($order_by).' '.$db->escape($direction).' LIMIT '.$start_from.', 50') or error('Unable to fetch ban list', __FILE__, __LINE__, $db->error()); - if ($db->num_rows($result)) - { - while ($ban_data = $db->fetch_assoc($result)) - { - - $actions = ''.$lang_admin_common['Edit'].' | '.$lang_admin_common['Remove'].''; - $expire = format_time($ban_data['expire'], true); - -?> - - - - - - - - - -'."\n"; - -?> - -
    '.pun_htmlspecialchars($ban_data['ban_creator_username']).'' : $lang_admin_bans['Unknown'] ?>
    '.$lang_admin_bans['No match'].'
    -
    -
    -
    - -
    -
    - -
      -
    • -
    • » 
    • -
    • » 
    • -
    -
    -
    -
    - -
    -

    -
    -
    -
    -
    - -
    - - - - - -
    - - -
    -
    -
    -
    -
    -
    - -

    -
    -
    -

    -
    -
    - -
    -

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    -
    -
    -     -
    -
    -
    -
    -

    -
    -
    -
    -
    - -query('INSERT INTO '.$db->prefix.'categories (cat_name) VALUES(\''.$db->escape($new_cat_name).'\')') or error('Unable to create category', __FILE__, __LINE__, $db->error()); - - redirect('admin_categories.php', $lang_admin_categories['Category added redirect']); -} - -// Delete a category -else if (isset($_POST['del_cat']) || isset($_POST['del_cat_comply'])) -{ - confirm_referrer('admin_categories.php'); - - $cat_to_delete = intval($_POST['cat_to_delete']); - if ($cat_to_delete < 1) - message($lang_common['Bad request']); - - if (isset($_POST['del_cat_comply'])) // Delete a category with all forums and posts - { - @set_time_limit(0); - - $result = $db->query('SELECT id FROM '.$db->prefix.'forums WHERE cat_id='.$cat_to_delete) or error('Unable to fetch forum list', __FILE__, __LINE__, $db->error()); - $num_forums = $db->num_rows($result); - - for ($i = 0; $i < $num_forums; ++$i) - { - $cur_forum = $db->result($result, $i); - - // Prune all posts and topics - prune($cur_forum, 1, -1); - - // Delete the forum - $db->query('DELETE FROM '.$db->prefix.'forums WHERE id='.$cur_forum) or error('Unable to delete forum', __FILE__, __LINE__, $db->error()); - } - - // Locate any "orphaned redirect topics" and delete them - $result = $db->query('SELECT t1.id FROM '.$db->prefix.'topics AS t1 LEFT JOIN '.$db->prefix.'topics AS t2 ON t1.moved_to=t2.id WHERE t2.id IS NULL AND t1.moved_to IS NOT NULL') or error('Unable to fetch redirect topics', __FILE__, __LINE__, $db->error()); - $num_orphans = $db->num_rows($result); - - if ($num_orphans) - { - for ($i = 0; $i < $num_orphans; ++$i) - $orphans[] = $db->result($result, $i); - - $db->query('DELETE FROM '.$db->prefix.'topics WHERE id IN('.implode(',', $orphans).')') or error('Unable to delete redirect topics', __FILE__, __LINE__, $db->error()); - } - - // Delete the category - $db->query('DELETE FROM '.$db->prefix.'categories WHERE id='.$cat_to_delete) or error('Unable to delete category', __FILE__, __LINE__, $db->error()); - - // Regenerate the quick jump cache - if (!defined('FORUM_CACHE_FUNCTIONS_LOADED')) - require PUN_ROOT.'include/cache.php'; - - generate_quickjump_cache(); - - redirect('admin_categories.php', $lang_admin_categories['Category deleted redirect']); - } - else // If the user hasn't comfirmed the delete - { - $result = $db->query('SELECT cat_name FROM '.$db->prefix.'categories WHERE id='.$cat_to_delete) or error('Unable to fetch category info', __FILE__, __LINE__, $db->error()); - $cat_name = $db->result($result); - - $page_title = array(pun_htmlspecialchars($pun_config['o_board_title']), $lang_admin_common['Admin'], $lang_admin_common['Categories']); - define('PUN_ACTIVE_PAGE', 'admin'); - require PUN_ROOT.'header.php'; - - generate_admin_menu('categories'); - -?> -
    -

    -
    -
    -
    - -
    - -
    -

    -

    -
    -
    -
    -

    -
    -
    -
    -
    - -query('SELECT id, disp_position FROM '.$db->prefix.'categories ORDER BY disp_position') or error('Unable to fetch category list', __FILE__, __LINE__, $db->error()); - $num_cats = $db->num_rows($result); - - for ($i = 0; $i < $num_cats; ++$i) - { - if ($cat_name[$i] == '') - message($lang_admin_categories['Must enter name message']); - - if ($cat_order[$i] == '' || preg_match('/[^0-9]/', $cat_order[$i])) - message($lang_admin_categories['Must enter integer message']); - - list($cat_id, $position) = $db->fetch_row($result); - - $db->query('UPDATE '.$db->prefix.'categories SET cat_name=\''.$db->escape($cat_name[$i]).'\', disp_position='.$cat_order[$i].' WHERE id='.$cat_id) or error('Unable to update category', __FILE__, __LINE__, $db->error()); - } - - // Regenerate the quick jump cache - if (!defined('FORUM_CACHE_FUNCTIONS_LOADED')) - require PUN_ROOT.'include/cache.php'; - - generate_quickjump_cache(); - - redirect('admin_categories.php', $lang_admin_categories['Categories updated redirect']); -} - -// Generate an array with all categories -$result = $db->query('SELECT id, cat_name, disp_position FROM '.$db->prefix.'categories ORDER BY disp_position') or error('Unable to fetch category list', __FILE__, __LINE__, $db->error()); -$num_cats = $db->num_rows($result); - -for ($i = 0; $i < $num_cats; ++$i) - $cat_list[] = $db->fetch_row($result); - -$page_title = array(pun_htmlspecialchars($pun_config['o_board_title']), $lang_admin_common['Admin'], $lang_admin_common['Categories']); -define('PUN_ACTIVE_PAGE', 'admin'); -require PUN_ROOT.'header.php'; - -generate_admin_menu('categories'); - -?> -
    -

    -
    -
    -
    -
    - -
    - - - - - -
    - - '.$lang_admin_common['Forums'].'') ?> -
    -
    -
    -
    -
    -
    - -

    -
    -
    -
    -
    - -
    - - - - - -
    - - -
    -
    -
    -
    -
    -
    - - -

    -
    -
    -
    -
    - -
    - - - - - - - - - $category) - { - -?> - - - - - - -
    -
    -
    -
    -
    -
    -
    -
    -
    - -query('INSERT INTO '.$db->prefix.'censoring (search_for, replace_with) VALUES (\''.$db->escape($search_for).'\', \''.$db->escape($replace_with).'\')') or error('Unable to add censor word', __FILE__, __LINE__, $db->error()); - - redirect('admin_censoring.php', $lang_admin_censoring['Word added redirect']); -} - -// Update a censor word -else if (isset($_POST['update'])) -{ - confirm_referrer('admin_censoring.php'); - - $id = intval(key($_POST['update'])); - - $search_for = pun_trim($_POST['search_for'][$id]); - $replace_with = pun_trim($_POST['replace_with'][$id]); - - if ($search_for == '' || $replace_with == '') - message($lang_admin_censoring['Must search both message']); - - $db->query('UPDATE '.$db->prefix.'censoring SET search_for=\''.$db->escape($search_for).'\', replace_with=\''.$db->escape($replace_with).'\' WHERE id='.$id) or error('Unable to update censor word', __FILE__, __LINE__, $db->error()); - - redirect('admin_censoring.php', $lang_admin_censoring['Word updated redirect']); -} - -// Remove a censor word -else if (isset($_POST['remove'])) -{ - confirm_referrer('admin_censoring.php'); - - $id = intval(key($_POST['remove'])); - - $db->query('DELETE FROM '.$db->prefix.'censoring WHERE id='.$id) or error('Unable to delete censor word', __FILE__, __LINE__, $db->error()); - - redirect('admin_censoring.php', $lang_admin_censoring['Word removed redirect']); -} - -$page_title = array(pun_htmlspecialchars($pun_config['o_board_title']), $lang_admin_common['Admin'], $lang_admin_common['Censoring']); -$focus_element = array('censoring', 'new_search_for'); -define('PUN_ACTIVE_PAGE', 'admin'); -require PUN_ROOT.'header.php'; - -generate_admin_menu('censoring'); - -?> -
    -

    -
    -
    -
    -
    - -
    -

    '.$lang_admin_common['Options'].'') ?>

    - - - - - - - - - - - - - - - -
    -
    -
    -
    -
    -
    - -
    -query('SELECT id, search_for, replace_with FROM '.$db->prefix.'censoring ORDER BY id') or error('Unable to fetch censor word list', __FILE__, __LINE__, $db->error()); -if ($db->num_rows($result)) -{ - -?> - - - - - - - - - -fetch_assoc($result)) - echo "\t\t\t\t\t\t\t\t".''."\n"; - -?> - -
     
    -'.$lang_admin_censoring['No words in list'].'

    '."\n"; - -?> -
    -
    -
    -
    -
    -
    -
    - -query('INSERT INTO '.$db->prefix.'forums (cat_id) VALUES('.$add_to_cat.')') or error('Unable to create forum', __FILE__, __LINE__, $db->error()); - - // Regenerate the quick jump cache - if (!defined('FORUM_CACHE_FUNCTIONS_LOADED')) - require PUN_ROOT.'include/cache.php'; - - generate_quickjump_cache(); - - redirect('admin_forums.php', $lang_admin_forums['Forum added redirect']); -} - -// Delete a forum -else if (isset($_GET['del_forum'])) -{ - confirm_referrer('admin_forums.php'); - - $forum_id = intval($_GET['del_forum']); - if ($forum_id < 1) - message($lang_common['Bad request']); - - if (isset($_POST['del_forum_comply'])) // Delete a forum with all posts - { - @set_time_limit(0); - - // Prune all posts and topics - prune($forum_id, 1, -1); - - // Locate any "orphaned redirect topics" and delete them - $result = $db->query('SELECT t1.id FROM '.$db->prefix.'topics AS t1 LEFT JOIN '.$db->prefix.'topics AS t2 ON t1.moved_to=t2.id WHERE t2.id IS NULL AND t1.moved_to IS NOT NULL') or error('Unable to fetch redirect topics', __FILE__, __LINE__, $db->error()); - $num_orphans = $db->num_rows($result); - - if ($num_orphans) - { - for ($i = 0; $i < $num_orphans; ++$i) - $orphans[] = $db->result($result, $i); - - $db->query('DELETE FROM '.$db->prefix.'topics WHERE id IN('.implode(',', $orphans).')') or error('Unable to delete redirect topics', __FILE__, __LINE__, $db->error()); - } - - // Delete the forum and any forum specific group permissions - $db->query('DELETE FROM '.$db->prefix.'forums WHERE id='.$forum_id) or error('Unable to delete forum', __FILE__, __LINE__, $db->error()); - $db->query('DELETE FROM '.$db->prefix.'forum_perms WHERE forum_id='.$forum_id) or error('Unable to delete group forum permissions', __FILE__, __LINE__, $db->error()); - - // Regenerate the quick jump cache - if (!defined('FORUM_CACHE_FUNCTIONS_LOADED')) - require PUN_ROOT.'include/cache.php'; - - generate_quickjump_cache(); - - redirect('admin_forums.php', $lang_admin_forums['Forum deleted redirect']); - } - else // If the user hasn't confirmed the delete - { - $result = $db->query('SELECT forum_name FROM '.$db->prefix.'forums WHERE id='.$forum_id) or error('Unable to fetch forum info', __FILE__, __LINE__, $db->error()); - $forum_name = pun_htmlspecialchars($db->result($result)); - - $page_title = array(pun_htmlspecialchars($pun_config['o_board_title']), $lang_admin_common['Admin'], $lang_admin_common['Forums']); - define('PUN_ACTIVE_PAGE', 'admin'); - require PUN_ROOT.'header.php'; - - generate_admin_menu('forums'); - -?> -
    -

    -
    -
    -
    -
    - -
    -

    -

    -
    -
    -
    -

    -
    -
    -
    -
    - - $disp_position) - { - $disp_position = trim($disp_position); - if ($disp_position == '' || preg_match('/[^0-9]/', $disp_position)) - message($lang_admin_forums['Must be integer message']); - - $db->query('UPDATE '.$db->prefix.'forums SET disp_position='.$disp_position.' WHERE id='.intval($forum_id)) or error('Unable to update forum', __FILE__, __LINE__, $db->error()); - } - - // Regenerate the quick jump cache - if (!defined('FORUM_CACHE_FUNCTIONS_LOADED')) - require PUN_ROOT.'include/cache.php'; - - generate_quickjump_cache(); - - redirect('admin_forums.php', $lang_admin_forums['Forums updated redirect']); -} - -else if (isset($_GET['edit_forum'])) -{ - $forum_id = intval($_GET['edit_forum']); - if ($forum_id < 1) - message($lang_common['Bad request']); - - // Update group permissions for $forum_id - if (isset($_POST['save'])) - { - confirm_referrer('admin_forums.php'); - - // Start with the forum details - $forum_name = pun_trim($_POST['forum_name']); - $forum_desc = pun_linebreaks(pun_trim($_POST['forum_desc'])); - $cat_id = intval($_POST['cat_id']); - $sort_by = intval($_POST['sort_by']); - $redirect_url = isset($_POST['redirect_url']) ? trim($_POST['redirect_url']) : null; - - if ($forum_name == '') - message($lang_admin_forums['Must enter name message']); - - if ($cat_id < 1) - message($lang_common['Bad request']); - - $forum_desc = ($forum_desc != '') ? '\''.$db->escape($forum_desc).'\'' : 'NULL'; - $redirect_url = ($redirect_url != '') ? '\''.$db->escape($redirect_url).'\'' : 'NULL'; - - $db->query('UPDATE '.$db->prefix.'forums SET forum_name=\''.$db->escape($forum_name).'\', forum_desc='.$forum_desc.', redirect_url='.$redirect_url.', sort_by='.$sort_by.', cat_id='.$cat_id.' WHERE id='.$forum_id) or error('Unable to update forum', __FILE__, __LINE__, $db->error()); - - // Now let's deal with the permissions - if (isset($_POST['read_forum_old'])) - { - $result = $db->query('SELECT g_id, g_read_board, g_post_replies, g_post_topics FROM '.$db->prefix.'groups WHERE g_id!='.PUN_ADMIN) or error('Unable to fetch user group list', __FILE__, __LINE__, $db->error()); - while ($cur_group = $db->fetch_assoc($result)) - { - $read_forum_new = ($cur_group['g_read_board'] == '1') ? isset($_POST['read_forum_new'][$cur_group['g_id']]) ? '1' : '0' : intval($_POST['read_forum_old'][$cur_group['g_id']]); - $post_replies_new = isset($_POST['post_replies_new'][$cur_group['g_id']]) ? '1' : '0'; - $post_topics_new = isset($_POST['post_topics_new'][$cur_group['g_id']]) ? '1' : '0'; - - // Check if the new settings differ from the old - if ($read_forum_new != $_POST['read_forum_old'][$cur_group['g_id']] || $post_replies_new != $_POST['post_replies_old'][$cur_group['g_id']] || $post_topics_new != $_POST['post_topics_old'][$cur_group['g_id']]) - { - // If the new settings are identical to the default settings for this group, delete it's row in forum_perms - if ($read_forum_new == '1' && $post_replies_new == $cur_group['g_post_replies'] && $post_topics_new == $cur_group['g_post_topics']) - $db->query('DELETE FROM '.$db->prefix.'forum_perms WHERE group_id='.$cur_group['g_id'].' AND forum_id='.$forum_id) or error('Unable to delete group forum permissions', __FILE__, __LINE__, $db->error()); - else - { - // Run an UPDATE and see if it affected a row, if not, INSERT - $db->query('UPDATE '.$db->prefix.'forum_perms SET read_forum='.$read_forum_new.', post_replies='.$post_replies_new.', post_topics='.$post_topics_new.' WHERE group_id='.$cur_group['g_id'].' AND forum_id='.$forum_id) or error('Unable to insert group forum permissions', __FILE__, __LINE__, $db->error()); - if (!$db->affected_rows()) - $db->query('INSERT INTO '.$db->prefix.'forum_perms (group_id, forum_id, read_forum, post_replies, post_topics) VALUES('.$cur_group['g_id'].', '.$forum_id.', '.$read_forum_new.', '.$post_replies_new.', '.$post_topics_new.')') or error('Unable to insert group forum permissions', __FILE__, __LINE__, $db->error()); - } - } - } - } - - // Regenerate the quick jump cache - if (!defined('FORUM_CACHE_FUNCTIONS_LOADED')) - require PUN_ROOT.'include/cache.php'; - - generate_quickjump_cache(); - - redirect('admin_forums.php', $lang_admin_forums['Forum updated redirect']); - } - else if (isset($_POST['revert_perms'])) - { - confirm_referrer('admin_forums.php'); - - $db->query('DELETE FROM '.$db->prefix.'forum_perms WHERE forum_id='.$forum_id) or error('Unable to delete group forum permissions', __FILE__, __LINE__, $db->error()); - - // Regenerate the quick jump cache - if (!defined('FORUM_CACHE_FUNCTIONS_LOADED')) - require PUN_ROOT.'include/cache.php'; - - generate_quickjump_cache(); - - redirect('admin_forums.php?edit_forum='.$forum_id, $lang_admin_forums['Perms reverted redirect']); - } - - // Fetch forum info - $result = $db->query('SELECT id, forum_name, forum_desc, redirect_url, num_topics, sort_by, cat_id FROM '.$db->prefix.'forums WHERE id='.$forum_id) or error('Unable to fetch forum info', __FILE__, __LINE__, $db->error()); - if (!$db->num_rows($result)) - message($lang_common['Bad request']); - - $cur_forum = $db->fetch_assoc($result); - - $page_title = array(pun_htmlspecialchars($pun_config['o_board_title']), $lang_admin_common['Admin'], $lang_admin_common['Forums']); - define('PUN_ACTIVE_PAGE', 'admin'); - require PUN_ROOT.'header.php'; - - generate_admin_menu('forums'); - -?> -
    -

    -
    -
    -

    -
    -
    - -
    - - - - - - - - - - - - - - - - - - - - - -
    - -
    - -
    '; ?>
    -
    -
    -
    -
    -
    - -
    -

    '.$lang_admin_common['User groups'].'') ?>

    - - - - - - - - - - -query('SELECT g.g_id, g.g_title, g.g_read_board, g.g_post_replies, g.g_post_topics, fp.read_forum, fp.post_replies, fp.post_topics FROM '.$db->prefix.'groups AS g LEFT JOIN '.$db->prefix.'forum_perms AS fp ON (g.g_id=fp.group_id AND fp.forum_id='.$forum_id.') WHERE g.g_id!='.PUN_ADMIN.' ORDER BY g.g_id') or error('Unable to fetch group forum permission list', __FILE__, __LINE__, $db->error()); - - while ($cur_perm = $db->fetch_assoc($result)) - { - $read_forum = ($cur_perm['read_forum'] != '0') ? true : false; - $post_replies = (($cur_perm['g_post_replies'] == '0' && $cur_perm['post_replies'] == '1') || ($cur_perm['g_post_replies'] == '1' && $cur_perm['post_replies'] != '0')) ? true : false; - $post_topics = (($cur_perm['g_post_topics'] == '0' && $cur_perm['post_topics'] == '1') || ($cur_perm['g_post_topics'] == '1' && $cur_perm['post_topics'] != '0')) ? true : false; - - // Determine if the current settings differ from the default or not - $read_forum_def = ($cur_perm['read_forum'] == '0') ? false : true; - $post_replies_def = (($post_replies && $cur_perm['g_post_replies'] == '0') || (!$post_replies && ($cur_perm['g_post_replies'] == '' || $cur_perm['g_post_replies'] == '1'))) ? false : true; - $post_topics_def = (($post_topics && $cur_perm['g_post_topics'] == '0') || (!$post_topics && ($cur_perm['g_post_topics'] == '' || $cur_perm['g_post_topics'] == '1'))) ? false : true; - -?> - - - > - - /> - - > - - /> - - > - - /> - - - - -
     
    -
    -
    -
    -
    -

    -
    -
    -
    -
    - - - -
    -

    -
    -
    -
    -
    - -
    - - - - - -
    - - -
    -
    -
    -
    -
    -
    -query('SELECT c.id AS cid, c.cat_name, f.id AS fid, f.forum_name, f.disp_position FROM '.$db->prefix.'categories AS c INNER JOIN '.$db->prefix.'forums AS f ON c.id=f.cat_id ORDER BY c.disp_position, c.id, f.disp_position') or error('Unable to fetch category/forum list', __FILE__, __LINE__, $db->error()); - -if ($db->num_rows($result) > 0) -{ - -?> -

    -
    -
    -

    -fetch_assoc($result)) -{ - if ($cur_forum['cid'] != $cur_category) // A new category since last iteration? - { - if ($cur_category != 0) - echo "\t\t\t\t\t\t\t".''."\n\t\t\t\t\t\t\t".''."\n\t\t\t\t\t\t".'
    '."\n\t\t\t\t\t".''."\n\t\t\t\t".'
    '."\n"; - -?> -
    -
    - -
    - - - - - - - - - - - - - - - - - -
    |
    -
    -
    -
    -

    - - - - -
    - -query('SELECT * FROM '.$db->prefix.'groups WHERE g_id='.$base_group) or error('Unable to fetch user group info', __FILE__, __LINE__, $db->error()); - $group = $db->fetch_assoc($result); - - $mode = 'add'; - } - else // We are editing a group - { - $group_id = intval($_GET['edit_group']); - if ($group_id < 1) - message($lang_common['Bad request']); - - $result = $db->query('SELECT * FROM '.$db->prefix.'groups WHERE g_id='.$group_id) or error('Unable to fetch user group info', __FILE__, __LINE__, $db->error()); - if (!$db->num_rows($result)) - message($lang_common['Bad request']); - - $group = $db->fetch_assoc($result); - - $mode = 'edit'; - } - - - $page_title = array(pun_htmlspecialchars($pun_config['o_board_title']), $lang_admin_common['Admin'], $lang_admin_common['User groups']); - $required_fields = array('req_title' => $lang_admin_groups['Group title label']); - $focus_element = array('groups2', 'req_title'); - define('PUN_ACTIVE_PAGE', 'admin'); - require PUN_ROOT.'header.php'; - - generate_admin_menu('groups'); - -?> -
    -

    -
    -
    -

    -
    - - - -
    - -
    -

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - -
    - tabindex="3" />     tabindex="4" />  - -
    - tabindex="5" />     tabindex="6" />  - -
    - tabindex="5" />     tabindex="6" />  - -
    - tabindex="5" />     tabindex="6" />  - -
    - tabindex="5" />     tabindex="6" />  - -
    - tabindex="3" />     tabindex="4" />  - -
    - tabindex="3" />     tabindex="4" />  - -
    - tabindex="5" />     tabindex="6" />  - -
    - tabindex="7" />     tabindex="8" />  - -
    - tabindex="11" />     tabindex="12" />  - -
    - tabindex="13" />     tabindex="14" />  - -
    - tabindex="15" />     tabindex="16" />  - -
    - tabindex="17" />     tabindex="18" />  - -
    - tabindex="19" />     tabindex="20" />  - -
    - tabindex="21" />     tabindex="22" />  - -
    - tabindex="21" />     tabindex="22" />  - -
    - - -
    - - -
    - - -
    -

    -
    -
    -
    -

    -
    -
    -
    -
    - -escape($user_title).'\'' : 'NULL'; - - if ($_POST['mode'] == 'add') - { - $result = $db->query('SELECT 1 FROM '.$db->prefix.'groups WHERE g_title=\''.$db->escape($title).'\'') or error('Unable to check group title collision', __FILE__, __LINE__, $db->error()); - if ($db->num_rows($result)) - message(sprintf($lang_admin_groups['Title already exists message'], pun_htmlspecialchars($title))); - - $db->query('INSERT INTO '.$db->prefix.'groups (g_title, g_user_title, g_moderator, g_mod_edit_users, g_mod_rename_users, g_mod_change_passwords, g_mod_ban_users, g_read_board, g_view_users, g_post_replies, g_post_topics, g_edit_posts, g_delete_posts, g_delete_topics, g_set_title, g_search, g_search_users, g_send_email, g_post_flood, g_search_flood, g_email_flood) VALUES(\''.$db->escape($title).'\', '.$user_title.', '.$moderator.', '.$mod_edit_users.', '.$mod_rename_users.', '.$mod_change_passwords.', '.$mod_ban_users.', '.$read_board.', '.$view_users.', '.$post_replies.', '.$post_topics.', '.$edit_posts.', '.$delete_posts.', '.$delete_topics.', '.$set_title.', '.$search.', '.$search_users.', '.$send_email.', '.$post_flood.', '.$search_flood.', '.$email_flood.')') or error('Unable to add group', __FILE__, __LINE__, $db->error()); - $new_group_id = $db->insert_id(); - - // Now lets copy the forum specific permissions from the group which this group is based on - $result = $db->query('SELECT forum_id, read_forum, post_replies, post_topics FROM '.$db->prefix.'forum_perms WHERE group_id='.intval($_POST['base_group'])) or error('Unable to fetch group forum permission list', __FILE__, __LINE__, $db->error()); - while ($cur_forum_perm = $db->fetch_assoc($result)) - $db->query('INSERT INTO '.$db->prefix.'forum_perms (group_id, forum_id, read_forum, post_replies, post_topics) VALUES('.$new_group_id.', '.$cur_forum_perm['forum_id'].', '.$cur_forum_perm['read_forum'].', '.$cur_forum_perm['post_replies'].', '.$cur_forum_perm['post_topics'].')') or error('Unable to insert group forum permissions', __FILE__, __LINE__, $db->error()); - } - else - { - $result = $db->query('SELECT 1 FROM '.$db->prefix.'groups WHERE g_title=\''.$db->escape($title).'\' AND g_id!='.intval($_POST['group_id'])) or error('Unable to check group title collision', __FILE__, __LINE__, $db->error()); - if ($db->num_rows($result)) - message(sprintf($lang_admin_groups['Title already exists message'], pun_htmlspecialchars($title))); - - $db->query('UPDATE '.$db->prefix.'groups SET g_title=\''.$db->escape($title).'\', g_user_title='.$user_title.', g_moderator='.$moderator.', g_mod_edit_users='.$mod_edit_users.', g_mod_rename_users='.$mod_rename_users.', g_mod_change_passwords='.$mod_change_passwords.', g_mod_ban_users='.$mod_ban_users.', g_read_board='.$read_board.', g_view_users='.$view_users.', g_post_replies='.$post_replies.', g_post_topics='.$post_topics.', g_edit_posts='.$edit_posts.', g_delete_posts='.$delete_posts.', g_delete_topics='.$delete_topics.', g_set_title='.$set_title.', g_search='.$search.', g_search_users='.$search_users.', g_send_email='.$send_email.', g_post_flood='.$post_flood.', g_search_flood='.$search_flood.', g_email_flood='.$email_flood.' WHERE g_id='.intval($_POST['group_id'])) or error('Unable to update group', __FILE__, __LINE__, $db->error()); - } - - // Regenerate the quick jump cache - if (!defined('FORUM_CACHE_FUNCTIONS_LOADED')) - require PUN_ROOT.'include/cache.php'; - - generate_quickjump_cache(); - - if ($_POST['mode'] == 'edit') - redirect('admin_groups.php', $lang_admin_groups['Group edited redirect']); - else - redirect('admin_groups.php', $lang_admin_groups['Group added redirect']); -} - - -// Set default group -else if (isset($_POST['set_default_group'])) -{ - confirm_referrer('admin_groups.php'); - - $group_id = intval($_POST['default_group']); - - // Make sure it's not the admin or guest groups - if ($group_id == PUN_ADMIN || $group_id == PUN_GUEST) - message($lang_common['Bad request']); - - // Make sure it's not a moderator group - $result = $db->query('SELECT 1 FROM '.$db->prefix.'groups WHERE g_id='.$group_id.' AND g_moderator=0') or error('Unable to check group moderator status', __FILE__, __LINE__, $db->error()); - if (!$db->num_rows($result)) - message($lang_common['Bad request']); - - $db->query('UPDATE '.$db->prefix.'config SET conf_value='.$group_id.' WHERE conf_name=\'o_default_user_group\'') or error('Unable to update board config', __FILE__, __LINE__, $db->error()); - - // Regenerate the config cache - if (!defined('FORUM_CACHE_FUNCTIONS_LOADED')) - require PUN_ROOT.'include/cache.php'; - - generate_config_cache(); - - redirect('admin_groups.php', $lang_admin_groups['Default group redirect']); -} - - -// Remove a group -else if (isset($_GET['del_group'])) -{ - confirm_referrer('admin_groups.php'); - - $group_id = isset($_POST['group_to_delete']) ? intval($_POST['group_to_delete']) : intval($_GET['del_group']); - if ($group_id < 5) - message($lang_common['Bad request']); - - // Make sure we don't remove the default group - if ($group_id == $pun_config['o_default_user_group']) - message($lang_admin_groups['Cannot remove default message']); - - // Check if this group has any members - $result = $db->query('SELECT g.g_title, COUNT(u.id) FROM '.$db->prefix.'groups AS g INNER JOIN '.$db->prefix.'users AS u ON g.g_id=u.group_id WHERE g.g_id='.$group_id.' GROUP BY g.g_id, g_title') or error('Unable to fetch group info', __FILE__, __LINE__, $db->error()); - - // If the group doesn't have any members or if we've already selected a group to move the members to - if (!$db->num_rows($result) || isset($_POST['del_group'])) - { - if (isset($_POST['del_group_comply']) || isset($_POST['del_group'])) - { - if (isset($_POST['del_group'])) - { - $move_to_group = intval($_POST['move_to_group']); - $db->query('UPDATE '.$db->prefix.'users SET group_id='.$move_to_group.' WHERE group_id='.$group_id) or error('Unable to move users into group', __FILE__, __LINE__, $db->error()); - } - - // Delete the group and any forum specific permissions - $db->query('DELETE FROM '.$db->prefix.'groups WHERE g_id='.$group_id) or error('Unable to delete group', __FILE__, __LINE__, $db->error()); - $db->query('DELETE FROM '.$db->prefix.'forum_perms WHERE group_id='.$group_id) or error('Unable to delete group forum permissions', __FILE__, __LINE__, $db->error()); - - // Regenerate the quick jump cache - if (!defined('FORUM_CACHE_FUNCTIONS_LOADED')) - require PUN_ROOT.'include/cache.php'; - - generate_quickjump_cache(); - - redirect('admin_groups.php', $lang_admin_groups['Group removed redirect']); - } - else - { - $result = $db->query('SELECT g_title FROM '.$db->prefix.'groups WHERE g_id='.$group_id) or error('Unable to fetch group title', __FILE__, __LINE__, $db->error()); - $group_title = $db->result($result); - - $page_title = array(pun_htmlspecialchars($pun_config['o_board_title']), $lang_admin_common['Admin'], $lang_admin_common['User groups']); - define('PUN_ACTIVE_PAGE', 'admin'); - require PUN_ROOT.'header.php'; - - generate_admin_menu('groups'); - -?> -
    -

    -
    -
    -
    - -
    - -
    -

    -

    -
    -
    -
    -

    -
    -
    -
    -
    - -fetch_row($result); - - $page_title = array(pun_htmlspecialchars($pun_config['o_board_title']), $lang_admin_common['Admin'], $lang_admin_common['User groups']); - define('PUN_ACTIVE_PAGE', 'admin'); - require PUN_ROOT.'header.php'; - - generate_admin_menu('groups'); - -?> -
    -

    -
    -
    -
    -
    - -
    -

    - -
    -
    -
    -

    -
    -
    -
    -
    - - -
    -

    -
    -
    -
    -
    - -
    - - - - - -
    - - -
    -
    -
    -
    -
    -
    - -
    - - - - - -
    - - -
    -
    -
    -
    -
    -
    - -

    -
    -
    -
    -
    - -
    -

    - -query('SELECT g_id, g_title FROM '.$db->prefix.'groups ORDER BY g_id') or error('Unable to fetch user group list', __FILE__, __LINE__, $db->error()); - -while ($cur_group = $db->fetch_assoc($result)) - echo "\t\t\t\t\t\t\t\t".''."\n"; - -?> -
    '.$lang_admin_groups['Edit link'].''.(($cur_group['g_id'] > PUN_MEMBER) ? ' | '.$lang_admin_groups['Delete link'].'' : '').''.pun_htmlspecialchars($cur_group['g_title']).'
    -
    -
    -
    -
    -
    -
    -
    - -=')) - message($lang_admin_index['Running latest version message']); - else - message(sprintf($lang_admin_index['New version available message'], 'FluxBB.org')); -} - - -// Show phpinfo() output -else if ($action == 'phpinfo' && $pun_user['g_id'] == PUN_ADMIN) -{ - // Is phpinfo() a disabled function? - if (strpos(strtolower((string) ini_get('disable_functions')), 'phpinfo') !== false) - message($lang_admin_index['PHPinfo disabled message']); - - phpinfo(); - exit; -} - - -// Get the server load averages (if possible) -if (@file_exists('/proc/loadavg') && is_readable('/proc/loadavg')) -{ - // We use @ just in case - $fh = @fopen('/proc/loadavg', 'r'); - $load_averages = @fread($fh, 64); - @fclose($fh); - - if (($fh = @fopen('/proc/loadavg', 'r'))) - { - $load_averages = fread($fh, 64); - fclose($fh); - } - else - $load_averages = ''; - - $load_averages = @explode(' ', $load_averages); - $server_load = isset($load_averages[2]) ? $load_averages[0].' '.$load_averages[1].' '.$load_averages[2] : $lang_admin_index['Not available']; -} -else if (!in_array(PHP_OS, array('WINNT', 'WIN32')) && preg_match('/averages?: ([0-9\.]+),?\s+([0-9\.]+),?\s+([0-9\.]+)/i', @exec('uptime'), $load_averages)) - $server_load = $load_averages[1].' '.$load_averages[2].' '.$load_averages[3]; -else - $server_load = $lang_admin_index['Not available']; - - -// Get number of current visitors -$result = $db->query('SELECT COUNT(user_id) FROM '.$db->prefix.'online WHERE idle=0') or error('Unable to fetch online count', __FILE__, __LINE__, $db->error()); -$num_online = $db->result($result); - - -// Collect some additional info about MySQL -if ($db_type == 'mysql' || $db_type == 'mysqli' || $db_type == 'mysql_innodb' || $db_type == 'mysqli_innodb') -{ - // Calculate total db size/row count - $result = $db->query('SHOW TABLE STATUS FROM `'.$db_name.'`') or error('Unable to fetch table status', __FILE__, __LINE__, $db->error()); - - $total_records = $total_size = 0; - while ($status = $db->fetch_assoc($result)) - { - $total_records += $status['Rows']; - $total_size += $status['Data_length'] + $status['Index_length']; - } - - $total_size = file_size($total_size); -} - - -// Check for the existence of various PHP opcode caches/optimizers -if (function_exists('mmcache')) - $php_accelerator = ''.$lang_admin_index['Turck MMCache'].''; -else if (isset($_PHPA)) - $php_accelerator = ''.$lang_admin_index['ionCube PHP Accelerator'].''; -else if (ini_get('apc.enabled')) - $php_accelerator =''.$lang_admin_index['Alternative PHP Cache (APC)'].''; -else if (ini_get('zend_optimizer.optimization_level')) - $php_accelerator = ''.$lang_admin_index['Zend Optimizer'].''; -else if (ini_get('eaccelerator.enable')) - $php_accelerator = ''.$lang_admin_index['eAccelerator'].''; -else if (ini_get('xcache.cacher')) - $php_accelerator = ''.$lang_admin_index['XCache'].''; -else - $php_accelerator = $lang_admin_index['NA']; - - -$page_title = array(pun_htmlspecialchars($pun_config['o_board_title']), $lang_admin_common['Admin'], $lang_admin_common['Index']); -define('PUN_ACTIVE_PAGE', 'admin'); -require PUN_ROOT.'header.php'; - -generate_admin_menu('index'); - -?> -
    -

    -
    -
    -

    -

    -  -
    -  -
    -  -
    -  -
    -  -
    -  -
    -  -
    -  -
    -  - -

    -
    -
    - -

    -
    -
    -
    -
    -
    - '.$lang_admin_index['Check for upgrade'].'') ?>
    -
    -
    -
    - -
    -
    -
    -
    - '.$lang_admin_index['Show info'].'') ?>
    - -
    -
    -
    - get_version())."\n" ?> -
    -
    -
    -
    -
    -
    -
    -
    - - -
    - -truncate_table('search_matches') or error('Unable to empty search index match table', __FILE__, __LINE__, $db->error()); - $db->truncate_table('search_words') or error('Unable to empty search index words table', __FILE__, __LINE__, $db->error()); - - // Reset the sequence for the search words (not needed for SQLite) - switch ($db_type) - { - case 'mysql': - case 'mysqli': - case 'mysql_innodb': - case 'mysqli_innodb': - $result = $db->query('ALTER TABLE '.$db->prefix.'search_words auto_increment=1') or error('Unable to update table auto_increment', __FILE__, __LINE__, $db->error()); - break; - - case 'pgsql'; - $result = $db->query('SELECT setval(\''.$db->prefix.'search_words_id_seq\', 1, false)') or error('Unable to update sequence', __FILE__, __LINE__, $db->error()); - } - } - - $page_title = array(pun_htmlspecialchars($pun_config['o_board_title']), $lang_admin_maintenance['Rebuilding search index']); - -?> - - - - - -<?php echo generate_page_title($page_title) ?> - - - - -

    -
    - -query('SELECT p.id, p.message, t.subject, t.first_post_id FROM '.$db->prefix.'posts AS p INNER JOIN '.$db->prefix.'topics AS t ON t.id=p.topic_id WHERE p.id >= '.$start_at.' ORDER BY p.id ASC LIMIT '.$per_page) or error('Unable to fetch posts', __FILE__, __LINE__, $db->error()); - - $end_at = 0; - while ($cur_item = $db->fetch_assoc($result)) - { - echo '

    '.sprintf($lang_admin_maintenance['Processing post'], $cur_item['id']).'

    '."\n"; - - if ($cur_item['id'] == $cur_item['first_post_id']) - update_search_index('post', $cur_item['id'], $cur_item['message'], $cur_item['subject']); - else - update_search_index('post', $cur_item['id'], $cur_item['message']); - - $end_at = $cur_item['id']; - } - - // Check if there is more work to do - if ($end_at > 0) - { - $result = $db->query('SELECT id FROM '.$db->prefix.'posts WHERE id > '.$end_at.' ORDER BY id ASC LIMIT 1') or error('Unable to fetch next ID', __FILE__, __LINE__, $db->error()); - - if ($db->num_rows($result) > 0) - $query_str = '?i_per_page='.$per_page.'&i_start_at='.$db->result($result); - } - - $db->end_transaction(); - $db->close(); - - exit('

    '.sprintf($lang_admin_maintenance['Javascript redirect failed'], ''.$lang_admin_maintenance['Click here'].'').'

    '); -} - - -// Get the first post ID from the db -$result = $db->query('SELECT id FROM '.$db->prefix.'posts ORDER BY id ASC LIMIT 1') or error('Unable to fetch topic info', __FILE__, __LINE__, $db->error()); -if ($db->num_rows($result)) - $first_id = $db->result($result); - -$page_title = array(pun_htmlspecialchars($pun_config['o_board_title']), $lang_admin_common['Admin'], $lang_admin_common['Maintenance']); -define('PUN_ACTIVE_PAGE', 'admin'); -require PUN_ROOT.'header.php'; - -generate_admin_menu('maintenance'); - -?> -
    -

    -
    -
    -
    -
    - -
    -

    '.$lang_admin_common['Maintenance mode'].'') ?>

    - - - - - - - - - - - - - -
    - - -
    - - -
    -    -
    -

    -
    -
    -
    -
    -
    -
    -
    -
    - - pun_trim($_POST['form']['board_title']), - 'board_desc' => pun_trim($_POST['form']['board_desc']), - 'base_url' => pun_trim($_POST['form']['base_url']), - 'default_timezone' => floatval($_POST['form']['default_timezone']), - 'default_dst' => $_POST['form']['default_dst'] != '1' ? '0' : '1', - 'default_lang' => preg_replace('#[\.\\\/]#', '', pun_trim($_POST['form']['default_lang'])), - 'default_style' => preg_replace('#[\.\\\/]#', '', pun_trim($_POST['form']['default_style'])), - 'time_format' => pun_trim($_POST['form']['time_format']), - 'date_format' => pun_trim($_POST['form']['date_format']), - 'timeout_visit' => intval($_POST['form']['timeout_visit']), - 'timeout_online' => intval($_POST['form']['timeout_online']), - 'redirect_delay' => intval($_POST['form']['redirect_delay']), - 'show_version' => $_POST['form']['show_version'] != '1' ? '0' : '1', - 'show_user_info' => $_POST['form']['show_user_info'] != '1' ? '0' : '1', - 'show_post_count' => $_POST['form']['show_post_count'] != '1' ? '0' : '1', - 'smilies' => $_POST['form']['smilies'] != '1' ? '0' : '1', - 'smilies_sig' => $_POST['form']['smilies_sig'] != '1' ? '0' : '1', - 'make_links' => $_POST['form']['make_links'] != '1' ? '0' : '1', - 'topic_review' => intval($_POST['form']['topic_review']), - 'disp_topics_default' => intval($_POST['form']['disp_topics_default']), - 'disp_posts_default' => intval($_POST['form']['disp_posts_default']), - 'indent_num_spaces' => intval($_POST['form']['indent_num_spaces']), - 'quote_depth' => intval($_POST['form']['quote_depth']), - 'quickpost' => $_POST['form']['quickpost'] != '1' ? '0' : '1', - 'users_online' => $_POST['form']['users_online'] != '1' ? '0' : '1', - 'censoring' => $_POST['form']['censoring'] != '1' ? '0' : '1', - 'signatures' => $_POST['form']['signatures'] != '1' ? '0' : '1', - 'ranks' => $_POST['form']['ranks'] != '1' ? '0' : '1', - 'show_dot' => $_POST['form']['show_dot'] != '1' ? '0' : '1', - 'topic_views' => $_POST['form']['topic_views'] != '1' ? '0' : '1', - 'quickjump' => $_POST['form']['quickjump'] != '1' ? '0' : '1', - 'gzip' => $_POST['form']['gzip'] != '1' ? '0' : '1', - 'search_all_forums' => $_POST['form']['search_all_forums'] != '1' ? '0' : '1', - 'additional_navlinks' => pun_trim($_POST['form']['additional_navlinks']), - 'feed_type' => intval($_POST['form']['feed_type']), - 'report_method' => intval($_POST['form']['report_method']), - 'mailing_list' => pun_trim($_POST['form']['mailing_list']), - 'avatars' => $_POST['form']['avatars'] != '1' ? '0' : '1', - 'avatars_dir' => pun_trim($_POST['form']['avatars_dir']), - 'avatars_width' => intval($_POST['form']['avatars_width']), - 'avatars_height' => intval($_POST['form']['avatars_height']), - 'avatars_size' => intval($_POST['form']['avatars_size']), - 'admin_email' => strtolower(pun_trim($_POST['form']['admin_email'])), - 'webmaster_email' => strtolower(pun_trim($_POST['form']['webmaster_email'])), - 'subscriptions' => $_POST['form']['subscriptions'] != '1' ? '0' : '1', - 'smtp_host' => pun_trim($_POST['form']['smtp_host']), - 'smtp_user' => pun_trim($_POST['form']['smtp_user']), - 'smtp_pass' => pun_trim($_POST['form']['smtp_pass']), - 'smtp_ssl' => $_POST['form']['smtp_ssl'] != '1' ? '0' : '1', - 'regs_allow' => $_POST['form']['regs_allow'] != '1' ? '0' : '1', - 'regs_verify' => $_POST['form']['regs_verify'] != '1' ? '0' : '1', - 'regs_report' => $_POST['form']['regs_report'] != '1' ? '0' : '1', - 'rules' => $_POST['form']['rules'] != '1' ? '0' : '1', - 'rules_message' => pun_trim($_POST['form']['rules_message']), - 'default_email_setting' => intval($_POST['form']['default_email_setting']), - 'announcement' => $_POST['form']['announcement'] != '1' ? '0' : '1', - 'announcement_message' => pun_trim($_POST['form']['announcement_message']), - 'maintenance' => $_POST['form']['maintenance'] != '1' ? '0' : '1', - 'maintenance_message' => pun_trim($_POST['form']['maintenance_message']), - ); - - if ($form['board_title'] == '') - message($lang_admin_options['Must enter title message']); - - // Make sure base_url doesn't end with a slash - if (substr($form['base_url'], -1) == '/') - $form['base_url'] = substr($form['base_url'], 0, -1); - - if (!file_exists(PUN_ROOT.'lang/'.$form['default_lang'].'/common.php')) - message($lang_common['Bad request']); - if (!file_exists(PUN_ROOT.'style/'.$form['default_style'].'.css')) - message($lang_common['Bad request']); - - if ($form['time_format'] == '') - $form['time_format'] = 'H:i:s'; - - if ($form['date_format'] == '') - $form['date_format'] = 'Y-m-d'; - - - require PUN_ROOT.'include/email.php'; - - if (!is_valid_email($form['admin_email'])) - message($lang_admin_options['Invalid e-mail message']); - - if (!is_valid_email($form['webmaster_email'])) - message($lang_admin_options['Invalid webmaster e-mail message']); - - if ($form['mailing_list'] != '') - $form['mailing_list'] = strtolower(preg_replace('/\s/S', '', $form['mailing_list'])); - - // Make sure avatars_dir doesn't end with a slash - if (substr($form['avatars_dir'], -1) == '/') - $form['avatars_dir'] = substr($form['avatars_dir'], 0, -1); - - if ($form['additional_navlinks'] != '') - $form['additional_navlinks'] = pun_trim(pun_linebreaks($form['additional_navlinks'])); - - if ($form['announcement_message'] != '') - $form['announcement_message'] = pun_linebreaks($form['announcement_message']); - else - { - $form['announcement_message'] = $lang_admin_options['Enter announcement here']; - $form['announcement'] = '0'; - } - - if ($form['rules_message'] != '') - $form['rules_message'] = pun_linebreaks($form['rules_message']); - else - { - $form['rules_message'] = $lang_admin_options['Enter rules here']; - $form['rules'] = '0'; - } - - if ($form['maintenance_message'] != '') - $form['maintenance_message'] = pun_linebreaks($form['maintenance_message']); - else - { - $form['maintenance_message'] = $lang_admin_options['Default maintenance message']; - $form['maintenance'] = '0'; - } - - // Make sure the number of displayed topics and posts is between 3 and 75 - if ($form['disp_topics_default'] < 3) - $form['disp_topics_default'] = 3; - else if ($form['disp_topics_default'] > 75) - $form['disp_topics_default'] = 75; - - if ($form['disp_posts_default'] < 3) - $form['disp_posts_default'] = 3; - else if ($form['disp_posts_default'] > 75) - $form['disp_posts_default'] = 75; - - if ($form['feed_type'] < 0 || $form['feed_type'] > 2) - message($lang_common['Bad request']); - - if ($form['report_method'] < 0 || $form['report_method'] > 2) - message($lang_common['Bad request']); - - if ($form['default_email_setting'] < 0 || $form['default_email_setting'] > 2) - message($lang_common['Bad request']); - - if ($form['timeout_online'] >= $form['timeout_visit']) - message($lang_admin_options['Timeout error message']); - - foreach ($form as $key => $input) - { - // Only update values that have changed - if (array_key_exists('o_'.$key, $pun_config) && $pun_config['o_'.$key] != $input) - { - if ($input != '' || is_int($input)) - $value = '\''.$db->escape($input).'\''; - else - $value = 'NULL'; - - $db->query('UPDATE '.$db->prefix.'config SET conf_value='.$value.' WHERE conf_name=\'o_'.$db->escape($key).'\'') or error('Unable to update board config', __FILE__, __LINE__, $db->error()); - } - } - - // Regenerate the config cache - if (!defined('FORUM_CACHE_FUNCTIONS_LOADED')) - require PUN_ROOT.'include/cache.php'; - - generate_config_cache(); - - redirect('admin_options.php', $lang_admin_options['Options updated redirect']); -} - -$page_title = array(pun_htmlspecialchars($pun_config['o_board_title']), $lang_admin_common['Admin'], $lang_admin_common['Options']); -define('PUN_ACTIVE_PAGE', 'admin'); -require PUN_ROOT.'header.php'; - -generate_admin_menu('options'); - -?> -
    -

    -
    -
    -

    -
    - -
    - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - - -
    - - -
    - - -
    - - -
    - />     />  - -
    - - -
    - - -
    -
    -
    -
    -
    -
    - -
    - - - - - - - - - - - - - - - - - - - - - -
    - - '.$lang_admin_options['PHP manual'].'') ?> -
    - - '.$lang_admin_options['PHP manual'].'') ?> -
    - - -
    - - -
    - - -
    -
    -
    -
    -
    -
    - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - />     />  - -
    - />     />  - -
    - />     />  - -
    - />     />  - -
    - />     />  - -
    - />     />  - -
    - - -
    - - -
    - - -
    - - -
    - - -
    -
    -
    -
    -
    -
    - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - />     />  - -
    - />     />  - -
    - />     />  - '.$lang_admin_common['Censoring'].'') ?> -
    - />     />  - -
    - />     />  - '.$lang_admin_common['Ranks'].'') ?> -
    - />     />  - -
    - />     />  - -
    - />     />  - -
    - />     />  - -
    - />     />  - -
    - - -
    - />     />     />  - -
    -
    -
    -
    -
    -
    - -
    - - - - - - - - - -
    - />     />     />  - -
    - - -
    -
    -
    -
    -
    -
    - -
    - - - - - - - - - - - - - - - - - - - - - -
    - />     />  - -
    - - -
    - - -
    - - -
    - - -
    -
    -
    -
    -
    -
    - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - - -
    - - -
    - />     />  - -
    - - -
    - - -
    - - -
    - />     />  - -
    -
    -
    -
    -
    -
    - -
    - - - - - - - - - - - - - - - - - - - - - - - - - -
    - />     />  - -
    - />     />  - -
    - />     />  - -
    - />     />  - -
    - - -
    - - /> 
    - /> 
    - /> 
    -
    -
    -
    -
    -
    -
    - -
    - - - - - - - - - -
    - />     />  - -
    - - -
    -
    -
    -
    -
    -
    - -
    - - - - - - - - - -
    - />     />  - -
    - - -
    -
    -
    -
    -

    -
    -
    -
    -
    - -query('UPDATE '.$db->prefix.'config SET conf_value='.$input.' WHERE conf_name=\'p_'.$db->escape($key).'\'') or error('Unable to update board config', __FILE__, __LINE__, $db->error()); - } - - // Regenerate the config cache - if (!defined('FORUM_CACHE_FUNCTIONS_LOADED')) - require PUN_ROOT.'include/cache.php'; - - generate_config_cache(); - - redirect('admin_permissions.php', $lang_admin_permissions['Perms updated redirect']); -} - -$page_title = array(pun_htmlspecialchars($pun_config['o_board_title']), $lang_admin_common['Admin'], $lang_admin_common['Permissions']); -define('PUN_ACTIVE_PAGE', 'admin'); -require PUN_ROOT.'header.php'; - -generate_admin_menu('permissions'); - -?> -
    -

    -
    -
    -

    -
    - -
    - -
    - - - - - - - - - - - - - - - - - - - - - -
    - />     />  - -
    - />     />  - -
    - />     />  - -
    - />     />  - -
    - />     />  - -
    -
    -
    -
    -
    -
    - -
    - - - - - - - - - - - - - - - - - - - - - -
    - />     />  - -
    - />     />  - -
    - />     />  - -
    - - -
    - - -
    -
    -
    -
    -
    -
    - -
    - - - - - - - - - -
    - />     />  - -
    - />     />  - -
    -
    -
    -
    -

    -
    -
    -
    -
    - -query('SELECT id FROM '.$db->prefix.'forums') or error('Unable to fetch forum list', __FILE__, __LINE__, $db->error()); - $num_forums = $db->num_rows($result); - - for ($i = 0; $i < $num_forums; ++$i) - { - $fid = $db->result($result, $i); - - prune($fid, $prune_sticky, $prune_date); - update_forum($fid); - } - } - else - { - $prune_from = intval($prune_from); - prune($prune_from, $prune_sticky, $prune_date); - update_forum($prune_from); - } - - // Locate any "orphaned redirect topics" and delete them - $result = $db->query('SELECT t1.id FROM '.$db->prefix.'topics AS t1 LEFT JOIN '.$db->prefix.'topics AS t2 ON t1.moved_to=t2.id WHERE t2.id IS NULL AND t1.moved_to IS NOT NULL') or error('Unable to fetch redirect topics', __FILE__, __LINE__, $db->error()); - $num_orphans = $db->num_rows($result); - - if ($num_orphans) - { - for ($i = 0; $i < $num_orphans; ++$i) - $orphans[] = $db->result($result, $i); - - $db->query('DELETE FROM '.$db->prefix.'topics WHERE id IN('.implode(',', $orphans).')') or error('Unable to delete redirect topics', __FILE__, __LINE__, $db->error()); - } - - redirect('admin_prune.php', $lang_admin_prune['Posts pruned redirect']); - } - - $prune_days = trim($_POST['req_prune_days']); - if ($prune_days == '' || preg_match('/[^0-9]/', $prune_days)) - message($lang_admin_prune['Must be integer message']); - - $prune_date = time() - ($prune_days*86400); - $prune_from = $_POST['prune_from']; - - // Concatenate together the query for counting number of topics to prune - $sql = 'SELECT COUNT(id) FROM '.$db->prefix.'topics WHERE last_post<'.$prune_date.' AND moved_to IS NULL'; - - if (!$prune_sticky) - $sql .= ' AND sticky=\'0\''; - - if ($prune_from != 'all') - { - $prune_from = intval($prune_from); - $sql .= ' AND forum_id='.$prune_from; - - // Fetch the forum name (just for cosmetic reasons) - $result = $db->query('SELECT forum_name FROM '.$db->prefix.'forums WHERE id='.$prune_from) or error('Unable to fetch forum name', __FILE__, __LINE__, $db->error()); - $forum = '"'.pun_htmlspecialchars($db->result($result)).'"'; - } - else - $forum = $lang_admin_prune['All forums']; - - $result = $db->query($sql) or error('Unable to fetch topic prune count', __FILE__, __LINE__, $db->error()); - $num_topics = $db->result($result); - - if (!$num_topics) - message(sprintf($lang_admin_prune['No old topics message'], $prune_days)); - - - $page_title = array(pun_htmlspecialchars($pun_config['o_board_title']), $lang_admin_common['Admin'], $lang_admin_common['Prune']); - define('PUN_ACTIVE_PAGE', 'admin'); - require PUN_ROOT.'header.php'; - - generate_admin_menu('prune'); - -?> -
    -

    -
    -
    -
    - - - -
    - -
    -

    -

    -
    -
    -
    -

    -
    -
    -
    -
    - - $lang_admin_prune['Days old label']); - $focus_element = array('prune', 'req_prune_days'); - define('PUN_ACTIVE_PAGE', 'admin'); - require PUN_ROOT.'header.php'; - - generate_admin_menu('prune'); - -?> -
    -

    -
    -
    -
    - -
    - -
    - - - - - - - - - - - - - -
    - - -
    -       - -
    - - -
    -

    '.$lang_admin_common['Maintenance mode'].'') ?>

    -
    -
    -
    -
    -
    -
    -
    -
    - -query('SELECT 1 FROM '.$db->prefix.'ranks WHERE min_posts='.$min_posts) or error('Unable to fetch rank info', __FILE__, __LINE__, $db->error()); - if ($db->num_rows($result)) - message(sprintf($lang_admin_ranks['Dupe min posts message'], $min_posts)); - - $db->query('INSERT INTO '.$db->prefix.'ranks (rank, min_posts) VALUES(\''.$db->escape($rank).'\', '.$min_posts.')') or error('Unable to add rank', __FILE__, __LINE__, $db->error()); - - // Regenerate the ranks cache - if (!defined('FORUM_CACHE_FUNCTIONS_LOADED')) - require PUN_ROOT.'include/cache.php'; - - generate_ranks_cache(); - - redirect('admin_ranks.php', $lang_admin_ranks['Rank added redirect']); -} - - -// Update a rank -else if (isset($_POST['update'])) -{ - confirm_referrer('admin_ranks.php'); - - $id = intval(key($_POST['update'])); - - $rank = pun_trim($_POST['rank'][$id]); - $min_posts = trim($_POST['min_posts'][$id]); - - if ($rank == '') - message($lang_admin_ranks['Must enter title message']); - - if ($min_posts == '' || preg_match('/[^0-9]/', $min_posts)) - message($lang_admin_ranks['Must be integer message']); - - // Make sure there isn't already a rank with the same min_posts value - $result = $db->query('SELECT 1 FROM '.$db->prefix.'ranks WHERE id!='.$id.' AND min_posts='.$min_posts) or error('Unable to fetch rank info', __FILE__, __LINE__, $db->error()); - if ($db->num_rows($result)) - message(sprintf($lang_admin_ranks['Dupe min posts message'], $min_posts)); - - $db->query('UPDATE '.$db->prefix.'ranks SET rank=\''.$db->escape($rank).'\', min_posts='.$min_posts.' WHERE id='.$id) or error('Unable to update rank', __FILE__, __LINE__, $db->error()); - - // Regenerate the ranks cache - if (!defined('FORUM_CACHE_FUNCTIONS_LOADED')) - require PUN_ROOT.'include/cache.php'; - - generate_ranks_cache(); - - redirect('admin_ranks.php', $lang_admin_ranks['Rank updated redirect']); -} - - -// Remove a rank -else if (isset($_POST['remove'])) -{ - confirm_referrer('admin_ranks.php'); - - $id = intval(key($_POST['remove'])); - - $db->query('DELETE FROM '.$db->prefix.'ranks WHERE id='.$id) or error('Unable to delete rank', __FILE__, __LINE__, $db->error()); - - // Regenerate the ranks cache - if (!defined('FORUM_CACHE_FUNCTIONS_LOADED')) - require PUN_ROOT.'include/cache.php'; - - generate_ranks_cache(); - - redirect('admin_ranks.php', $lang_admin_ranks['Rank removed redirect']); -} - -$page_title = array(pun_htmlspecialchars($pun_config['o_board_title']), $lang_admin_common['Admin'], $lang_admin_common['Ranks']); -$focus_element = array('ranks', 'new_rank'); -define('PUN_ACTIVE_PAGE', 'admin'); -require PUN_ROOT.'header.php'; - -generate_admin_menu('ranks'); - -?> -
    -

    -
    -
    -
    -
    - -
    -

    '.$lang_admin_common['Options'].'') ?>

    - - - - - - - - - - - - - - - -
    -
    -
    -
    -
    -
    - -
    -query('SELECT id, rank, min_posts FROM '.$db->prefix.'ranks ORDER BY min_posts') or error('Unable to fetch rank list', __FILE__, __LINE__, $db->error()); -if ($db->num_rows($result)) -{ - -?> - - - - - - - - - -fetch_assoc($result)) - echo "\t\t\t\t\t\t\t\t".''."\n"; - -?> - -
     
    -'.$lang_admin_ranks['No ranks in list'].'

    '."\n"; - -?> -
    -
    -
    -
    -
    -
    -
    - -query('SELECT zapped FROM '.$db->prefix.'reports WHERE id='.$zap_id) or error('Unable to fetch report info', __FILE__, __LINE__, $db->error()); - $zapped = $db->result($result); - - if ($zapped == '') - $db->query('UPDATE '.$db->prefix.'reports SET zapped='.time().', zapped_by='.$pun_user['id'].' WHERE id='.$zap_id) or error('Unable to zap report', __FILE__, __LINE__, $db->error()); - - redirect('admin_reports.php', $lang_admin_reports['Report zapped redirect']); -} - - -$page_title = array(pun_htmlspecialchars($pun_config['o_board_title']), $lang_admin_common['Admin'], $lang_admin_common['Reports']); -define('PUN_ACTIVE_PAGE', 'admin'); -require PUN_ROOT.'header.php'; - -generate_admin_menu('reports'); - -?> -
    -

    -
    -
    -query('SELECT r.id, r.topic_id, r.forum_id, r.reported_by, r.created, r.message, p.id AS pid, t.subject, f.forum_name, u.username AS reporter FROM '.$db->prefix.'reports AS r LEFT JOIN '.$db->prefix.'posts AS p ON r.post_id=p.id LEFT JOIN '.$db->prefix.'topics AS t ON r.topic_id=t.id LEFT JOIN '.$db->prefix.'forums AS f ON r.forum_id=f.id LEFT JOIN '.$db->prefix.'users AS u ON r.reported_by=u.id WHERE r.zapped IS NULL ORDER BY created DESC') or error('Unable to fetch report list', __FILE__, __LINE__, $db->error()); - -if ($db->num_rows($result)) -{ - while ($cur_report = $db->fetch_assoc($result)) - { - $reporter = ($cur_report['reporter'] != '') ? ''.pun_htmlspecialchars($cur_report['reporter']).'' : $lang_admin_reports['Deleted user']; - $forum = ($cur_report['forum_name'] != '') ? ''.pun_htmlspecialchars($cur_report['forum_name']).'' : $lang_admin_reports['Deleted']; - $topic = ($cur_report['subject'] != '') ? ''.pun_htmlspecialchars($cur_report['subject']).'' : $lang_admin_reports['Deleted']; - $post = str_replace("\n", '
    ', pun_htmlspecialchars($cur_report['message'])); - $postid = ($cur_report['pid'] != '') ? 'Post #'.$cur_report['pid'].'' : $lang_admin_reports['Deleted']; - $report_location = array($forum, $topic, $postid); - -?> -
    -
    - -
    - - - - - - - - - -
    -
    -
    -
    - -
    -
    - -
    -

    -
    -
    -
    - -
    -
    -
    - -
    -

    -
    -
    -query('SELECT r.id, r.topic_id, r.forum_id, r.reported_by, r.message, r.zapped, r.zapped_by AS zapped_by_id, p.id AS pid, t.subject, f.forum_name, u.username AS reporter, u2.username AS zapped_by FROM '.$db->prefix.'reports AS r LEFT JOIN '.$db->prefix.'posts AS p ON r.post_id=p.id LEFT JOIN '.$db->prefix.'topics AS t ON r.topic_id=t.id LEFT JOIN '.$db->prefix.'forums AS f ON r.forum_id=f.id LEFT JOIN '.$db->prefix.'users AS u ON r.reported_by=u.id LEFT JOIN '.$db->prefix.'users AS u2 ON r.zapped_by=u2.id WHERE r.zapped IS NOT NULL ORDER BY zapped DESC LIMIT 10') or error('Unable to fetch report list', __FILE__, __LINE__, $db->error()); - -if ($db->num_rows($result)) -{ - while ($cur_report = $db->fetch_assoc($result)) - { - $reporter = ($cur_report['reporter'] != '') ? ''.pun_htmlspecialchars($cur_report['reporter']).'' : $lang_admin_reports['Deleted user']; - $forum = ($cur_report['forum_name'] != '') ? ''.pun_htmlspecialchars($cur_report['forum_name']).'' : $lang_admin_reports['Deleted']; - $topic = ($cur_report['subject'] != '') ? ''.pun_htmlspecialchars($cur_report['subject']).'' : $lang_admin_reports['Deleted']; - $post = str_replace("\n", '
    ', pun_htmlspecialchars($cur_report['message'])); - $post_id = ($cur_report['pid'] != '') ? 'Post #'.$cur_report['pid'].'' : $lang_admin_reports['Deleted']; - $zapped_by = ($cur_report['zapped_by'] != '') ? ''.pun_htmlspecialchars($cur_report['zapped_by']).'' : $lang_admin_reports['NA']; - $zapped_by = ($cur_report['zapped_by'] != '') ? ''.pun_htmlspecialchars($cur_report['zapped_by']).'' : $lang_admin_reports['NA']; - $report_location = array($forum, $topic, $post_id); - -?> -
    -
    - -
    - - - - - - - - - -
    -
    -
    -
    - -
    -
    - -
    -

    -
    -
    -
    - -
    -
    -
    -
    - -query('SELECT poster_ip, MAX(posted) AS last_used FROM '.$db->prefix.'posts WHERE poster_id='.$ip_stats.' GROUP BY poster_ip') or error('Unable to fetch post info', __FILE__, __LINE__, $db->error()); - $num_ips = $db->num_rows($result); - - // Determine the ip offset (based on $_GET['p']) - $num_pages = ceil($num_ips / 50); - - $p = (!isset($_GET['p']) || $_GET['p'] <= 1 || $_GET['p'] > $num_pages) ? 1 : intval($_GET['p']); - $start_from = 50 * ($p - 1); - - // Generate paging links - $paging_links = ''.$lang_common['Pages'].' '.paginate($num_pages, $p, 'admin_users.php?ip_stats='.$ip_stats ); - - $page_title = array(pun_htmlspecialchars($pun_config['o_board_title']), $lang_admin_common['Admin'], $lang_admin_common['Users'], $lang_admin_users['Results head']); - define('PUN_ACTIVE_PAGE', 'admin'); - require PUN_ROOT.'header.php'; - -?> -
    -
    -
      -
    • -
    • » 
    • -
    • » 
    • -
    - -
    -
    -
    - -
    -

    -
    -
    - - - - - - - - - - -query('SELECT poster_ip, MAX(posted) AS last_used, COUNT(id) AS used_times FROM '.$db->prefix.'posts WHERE poster_id='.$ip_stats.' GROUP BY poster_ip ORDER BY last_used DESC LIMIT '.$start_from.', 50') or error('Unable to fetch post info', __FILE__, __LINE__, $db->error()); - if ($db->num_rows($result)) - { - while ($cur_ip = $db->fetch_assoc($result)) - { - -?> - - - - - - -'."\n"; - -?> - -
    '.$lang_admin_users['Results no posts found'].'
    -
    -
    -
    - -
    -
    - -
      -
    • -
    • » 
    • -
    • » 
    • -
    -
    -
    -
    -query('SELECT DISTINCT poster_id, poster FROM '.$db->prefix.'posts WHERE poster_ip=\''.$db->escape($ip).'\'') or error('Unable to fetch post info', __FILE__, __LINE__, $db->error()); - $num_users = $db->num_rows($result); - - // Determine the user offset (based on $_GET['p']) - $num_pages = ceil($num_users / 50); - - $p = (!isset($_GET['p']) || $_GET['p'] <= 1 || $_GET['p'] > $num_pages) ? 1 : intval($_GET['p']); - $start_from = 50 * ($p - 1); - - // Generate paging links - $paging_links = ''.$lang_common['Pages'].' '.paginate($num_pages, $p, 'admin_users.php?show_users='.$ip); - - $page_title = array(pun_htmlspecialchars($pun_config['o_board_title']), $lang_admin_common['Admin'], $lang_admin_common['Users'], $lang_admin_users['Results head']); - define('PUN_ACTIVE_PAGE', 'admin'); - require PUN_ROOT.'header.php'; - -?> -
    -
    -
      -
    • -
    • » 
    • -
    • » 
    • -
    - -
    -
    -
    - -
    -

    -
    -
    - - - - - - - - - - - - -query('SELECT DISTINCT poster_id, poster FROM '.$db->prefix.'posts WHERE poster_ip=\''.$db->escape($ip).'\' ORDER BY poster DESC') or error('Unable to fetch post info', __FILE__, __LINE__, $db->error()); - $num_posts = $db->num_rows($result); - - if ($num_posts) - { - // Loop through users and print out some info - for ($i = 0; $i < $num_posts; ++$i) - { - list($poster_id, $poster) = $db->fetch_row($result); - - $result2 = $db->query('SELECT u.id, u.username, u.email, u.title, u.num_posts, u.admin_note, g.g_id, g.g_user_title FROM '.$db->prefix.'users AS u INNER JOIN '.$db->prefix.'groups AS g ON g.g_id=u.group_id WHERE u.id>1 AND u.id='.$poster_id) or error('Unable to fetch user info', __FILE__, __LINE__, $db->error()); - - if (($user_data = $db->fetch_assoc($result2))) - { - $user_title = get_title($user_data); - - $actions = ''.$lang_admin_users['Results view IP link'].' | '.$lang_admin_users['Results show posts link'].''; - -?> - - - - - - - - - - - - - - - - - -'."\n"; - -?> - -
    '.pun_htmlspecialchars($user_data['username']).'' ?>
        
    '.$lang_admin_users['Results no IP found'].'
    -
    -
    -
    - -
    -
    - -
      -
    • -
    • » 
    • -
    • » 
    • -
    -
    -
    -
    -'.$last_post_after; - } - if ($last_post_before != '') - { - $query_str[] = 'last_post_before='.$last_post_before; - - $last_post_before = strtotime($last_post_before); - if ($last_post_before === false || $last_post_before == -1) - message($lang_admin_users['Invalid date time message']); - - $conditions[] = 'u.last_post<'.$last_post_before; - } - if ($registered_after != '') - { - $query_str[] = 'registered_after='.$registered_after; - - $registered_after = strtotime($registered_after); - if ($registered_after === false || $registered_after == -1) - message($lang_admin_users['Invalid date time message']); - - $conditions[] = 'u.registered>'.$registered_after; - } - if ($registered_before != '') - { - $query_str[] = 'registered_before='.$registered_before; - - $registered_before = strtotime($registered_before); - if ($registered_before === false || $registered_before == -1) - message($lang_admin_users['Invalid date time message']); - - $conditions[] = 'u.registered<'.$registered_before; - } - - $like_command = ($db_type == 'pgsql') ? 'ILIKE' : 'LIKE'; - while (list($key, $input) = @each($form)) - { - if ($input != '' && in_array($key, array('username', 'email', 'title', 'realname', 'url', 'jabber', 'icq', 'msn', 'aim', 'yahoo', 'location', 'signature', 'admin_note'))) - { - $conditions[] = 'u.'.$db->escape($key).' '.$like_command.' \''.$db->escape(str_replace('*', '%', $input)).'\''; - $query_str[] = 'form%5B'.$key.'%5D='.urlencode($input); - } - } - - if ($posts_greater != '') - { - $query_str[] = 'posts_greater='.$posts_greater; - $conditions[] = 'u.num_posts>'.$posts_greater; - } - if ($posts_less != '') - { - $query_str[] = 'posts_less='.$posts_less; - $conditions[] = 'u.num_posts<'.$posts_less; - } - - if ($user_group > -1) - $conditions[] = 'u.group_id='.$user_group; - - // Fetch user count - $result = $db->query('SELECT COUNT(id) FROM '.$db->prefix.'users AS u LEFT JOIN '.$db->prefix.'groups AS g ON g.g_id=u.group_id WHERE u.id>1'.(!empty($conditions) ? ' AND '.implode(' AND ', $conditions) : '')) or error('Unable to fetch user info', __FILE__, __LINE__, $db->error()); - $num_users = $db->result($result); - - // Determine the user offset (based on $_GET['p']) - $num_pages = ceil($num_users / 50); - - $p = (!isset($_GET['p']) || $_GET['p'] <= 1 || $_GET['p'] > $num_pages) ? 1 : intval($_GET['p']); - $start_from = 50 * ($p - 1); - - // Generate paging links - $paging_links = ''.$lang_common['Pages'].' '.paginate($num_pages, $p, 'admin_users.php?find_user=&'.implode('&', $query_str)); - - $page_title = array(pun_htmlspecialchars($pun_config['o_board_title']), $lang_admin_common['Admin'], $lang_admin_common['Users'], $lang_admin_users['Results head']); - define('PUN_ACTIVE_PAGE', 'admin'); - require PUN_ROOT.'header.php'; - -?> -
    -
    -
      -
    • -
    • » 
    • -
    • » 
    • -
    - -
    -
    -
    - - -
    -

    -
    -
    - - - - - - - - - - - - -query('SELECT u.id, u.username, u.email, u.title, u.num_posts, u.admin_note, g.g_id, g.g_user_title FROM '.$db->prefix.'users AS u LEFT JOIN '.$db->prefix.'groups AS g ON g.g_id=u.group_id WHERE u.id>1'.(!empty($conditions) ? ' AND '.implode(' AND ', $conditions) : '').' ORDER BY '.$db->escape($order_by).' '.$db->escape($direction).' LIMIT '.$start_from.', 50') or error('Unable to fetch user info', __FILE__, __LINE__, $db->error()); - if ($db->num_rows($result)) - { - while ($user_data = $db->fetch_assoc($result)) - { - $user_title = get_title($user_data); - - // This script is a special case in that we want to display "Not verified" for non-verified users - if (($user_data['g_id'] == '' || $user_data['g_id'] == PUN_UNVERIFIED) && $user_title != $lang_common['Banned']) - $user_title = ''.$lang_admin_users['Not verified'].''; - - $actions = ''.$lang_admin_users['Results view IP link'].' | '.$lang_admin_users['Results show posts link'].''; - -?> - - - - - - - - -'."\n"; - -?> - -
    '.pun_htmlspecialchars($user_data['username']).'' ?>
    '.$lang_admin_users['No match'].'
    -
    -
    -
    - -
    -
    - -
      -
    • -
    • » 
    • -
    • » 
    • -
    -
    -
    -
    - -
    -

    -
    -
    -

    -
    -
    - -
    -

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    -
    -
    -
    -
    -     -
    - -
    -
    -
    -
    -

    -
    -
    - -

    -
    -
    -
    -
    - -
    - - - - - -
    -
    -
    -
    -
    -
    -
    -
    -
    - - -Order Allow,Deny -Deny from All - diff --git a/upload/cache/index.html b/upload/cache/index.html deleted file mode 100644 index 89337b2..0000000 --- a/upload/cache/index.html +++ /dev/null @@ -1 +0,0 @@ -.. diff --git a/upload/db_update.php b/upload/db_update.php deleted file mode 100644 index 6cf36eb..0000000 --- a/upload/db_update.php +++ /dev/null @@ -1,1427 +0,0 @@ -query('SELECT conf_value FROM '.$db->prefix.'config WHERE conf_name=\'o_cur_version\'') or error('Unable to fetch version info.', __FILE__, __LINE__, $db->error()); -$cur_version = $db->result($result); - -if (version_compare($cur_version, '1.2', '<')) - exit('Version mismatch. The database \''.$db_name.'\' doesn\'t seem to be running a FluxBB database schema supported by this update script.'); - -// Do some DB type specific checks -$mysql = false; -switch ($db_type) -{ - case 'mysql': - case 'mysqli': - case 'mysql_innodb': - case 'mysqli_innodb': - $mysql_info = $db->get_version(); - if (version_compare($mysql_info['version'], MIN_MYSQL_VERSION, '<')) - error('You are running MySQL version '.$mysql_version.'. FluxBB '.UPDATE_TO.' requires at least MySQL '.MIN_MYSQL_VERSION.' to run properly. You must upgrade your MySQL installation before you can continue.'); - - $mysql = true; - break; - - case 'pgsql': - $pgsql_info = $db->get_version(); - if (version_compare($pgsql_info['version'], MIN_PGSQL_VERSION, '<')) - error('You are running PostgreSQL version '.$pgsql_info.'. FluxBB '.UPDATE_TO.' requires at least PostgreSQL '.MIN_PGSQL_VERSION.' to run properly. You must upgrade your PostgreSQL installation before you can continue.'); - - break; -} - -// Get the forum config -$result = $db->query('SELECT * FROM '.$db->prefix.'config') or error('Unable to fetch config.', __FILE__, __LINE__, $db->error()); -while ($cur_config_item = $db->fetch_row($result)) - $pun_config[$cur_config_item[0]] = $cur_config_item[1]; - -// Check the database revision and the current version -if (isset($pun_config['o_database_revision']) && $pun_config['o_database_revision'] >= UPDATE_TO_DB_REVISION && version_compare($pun_config['o_cur_version'], UPDATE_TO, '>=')) - exit('Your database is already as up-to-date as this script can make it.'); - -$default_style = $pun_config['o_default_style']; -if (!file_exists(PUN_ROOT.'style/'.$default_style.'.css')) - $default_style = 'Air'; - -// -// Determines whether $str is UTF-8 encoded or not -// -function seems_utf8($str) -{ - $str_len = strlen($str); - for ($i = 0; $i < $str_len; ++$i) - { - if (ord($str[$i]) < 0x80) continue; # 0bbbbbbb - else if ((ord($str[$i]) & 0xE0) == 0xC0) $n=1; # 110bbbbb - else if ((ord($str[$i]) & 0xF0) == 0xE0) $n=2; # 1110bbbb - else if ((ord($str[$i]) & 0xF8) == 0xF0) $n=3; # 11110bbb - else if ((ord($str[$i]) & 0xFC) == 0xF8) $n=4; # 111110bb - else if ((ord($str[$i]) & 0xFE) == 0xFC) $n=5; # 1111110b - else return false; # Does not match any model - - for ($j = 0; $j < $n; ++$j) # n bytes matching 10bbbbbb follow ? - { - if ((++$i == strlen($str)) || ((ord($str[$i]) & 0xC0) != 0x80)) - return false; - } - } - - return true; -} - - -// -// Translates the number from a HTML numeric entity into an UTF-8 character -// -function dcr2utf8($src) -{ - $dest = ''; - if ($src < 0) - return false; - else if ($src <= 0x007f) - $dest .= chr($src); - else if ($src <= 0x07ff) - { - $dest .= chr(0xc0 | ($src >> 6)); - $dest .= chr(0x80 | ($src & 0x003f)); - } - else if ($src == 0xFEFF) - { - // nop -- zap the BOM - } - else if ($src >= 0xD800 && $src <= 0xDFFF) - { - // found a surrogate - return false; - } - else if ($src <= 0xffff) - { - $dest .= chr(0xe0 | ($src >> 12)); - $dest .= chr(0x80 | (($src >> 6) & 0x003f)); - $dest .= chr(0x80 | ($src & 0x003f)); - } - else if ($src <= 0x10ffff) - { - $dest .= chr(0xf0 | ($src >> 18)); - $dest .= chr(0x80 | (($src >> 12) & 0x3f)); - $dest .= chr(0x80 | (($src >> 6) & 0x3f)); - $dest .= chr(0x80 | ($src & 0x3f)); - } - else - { - // out of range - return false; - } - - return $dest; -} - - -// -// Attempts to convert $str from $old_charset to UTF-8. Also converts HTML entities (including numeric entities) to UTF-8 characters -// -function convert_to_utf8(&$str, $old_charset) -{ - if ($str === null || $str == '') - return false; - - $save = $str; - - // Replace literal entities (for non-UTF-8 compliant html_entity_encode) - if (version_compare(PHP_VERSION, '5.0.0', '<') && $old_charset == 'ISO-8859-1' || $old_charset == 'ISO-8859-15') - $str = html_entity_decode($str, ENT_QUOTES, $old_charset); - - if ($old_charset != 'UTF-8' && !seems_utf8($str)) - { - if (function_exists('iconv')) - $str = iconv($old_charset == 'ISO-8859-1' ? 'WINDOWS-1252' : 'ISO-8859-1', 'UTF-8', $str); - else if (function_exists('mb_convert_encoding')) - $str = mb_convert_encoding($str, 'UTF-8', $old_charset == 'ISO-8859-1' ? 'WINDOWS-1252' : 'ISO-8859-1'); - else if ($old_charset == 'ISO-8859-1') - $str = utf8_encode($str); - } - - // Replace literal entities (for UTF-8 compliant html_entity_encode) - if (version_compare(PHP_VERSION, '5.0.0', '>=')) - $str = html_entity_decode($str, ENT_QUOTES, 'UTF-8'); - - // Replace numeric entities - $str = preg_replace_callback('/&#([0-9]+);/', 'utf8_callback_1', $str); - $str = preg_replace_callback('/&#x([a-f0-9]+);/i', 'utf8_callback_2', $str); - - // Remove "bad" characters - $str = remove_bad_characters($str); - - return ($save != $str); -} - - -function utf8_callback_1($matches) -{ - return dcr2utf8($matches[1]); -} - - -function utf8_callback_2($matches) -{ - return dcr2utf8(hexdec($matches[1])); -} - - -// -// Alter a table to be utf8. MySQL only -// Function based on update_convert_table_utf8() from the Drupal project (http://drupal.org/) -// -function alter_table_utf8($table) -{ - global $mysql, $db; - static $types; - - if (!$mysql) - return; - - if (!isset($types)) - { - $types = array( - 'char' => 'binary', - 'varchar' => 'varbinary', - 'tinytext' => 'tinyblob', - 'mediumtext' => 'mediumblob', - 'text' => 'blob', - 'longtext' => 'longblob' - ); - } - - // Set table default charset to utf8 - $db->query('ALTER TABLE '.$table.' CHARACTER SET utf8') or error('Unable to set table character set', __FILE__, __LINE__, $db->error()); - - // Find out which columns need converting and build SQL statements - $result = $db->query('SHOW FULL COLUMNS FROM '.$table) or error('Unable to fetch column information', __FILE__, __LINE__, $db->error()); - while ($cur_column = $db->fetch_assoc($result)) - { - if ($cur_column['Collation'] === null) - continue; - - list($type) = explode('(', $cur_column['Type']); - if (isset($types[$type]) && strpos($cur_column['Collation'], 'utf8') === false) - { - $allow_null = ($cur_column['Null'] == 'YES'); - $collate = (substr($cur_column['Collation'], -3) == 'bin') ? 'utf8_bin' : 'utf8_general_ci'; - - $db->alter_field($table, $cur_column['Field'], preg_replace('/'.$type.'/i', $types[$type], $cur_column['Type']), $allow_null, $cur_column['Default'], null, true) or error('Unable to alter field to binary', __FILE__, __LINE__, $db->error()); - $db->alter_field($table, $cur_column['Field'], $cur_column['Type'].' CHARACTER SET utf8 COLLATE '.$collate, $allow_null, $cur_column['Default'], null, true) or error('Unable to alter field to utf8', __FILE__, __LINE__, $db->error()); - } - } -} - -// -// Safely converts text type columns into utf8 -// If finished returns true, otherwise returns $end_at -// -function convert_table_utf8($table, $callback, $old_charset, $key = null, $start_at = null) -{ - global $mysql, $db; - - $finished = true; - $end_at = 0; - if ($mysql) - { - // Only set up the tables if we are doing this in 1 go, or its the first go - if ($start_at === null || $start_at == 0) - { - // Drop any temp table that exists, in-case it's left over from a failed update - $db->drop_table($table.'_utf8', true) or error('Unable to drop left over temp table', __FILE__, __LINE__, $db->error()); - - // Copy the table - $db->query('CREATE TABLE '.$table.'_utf8 LIKE '.$table) or error('Unable to create new table', __FILE__, __LINE__, $db->error()); - - // Set table default charset to utf8 - alter_table_utf8($table.'_utf8'); - } - - // Change to latin1 mode so MySQL doesn't attempt to perform conversion on the data from the old table - $db->set_names('latin1'); - - // Move & Convert everything - $result = $db->query('SELECT * FROM '.$table.($start_at === null ? '' : ' WHERE '.$key.'>'.$start_at).' ORDER BY '.$key.' ASC'.($start_at === null ? '' : ' LIMIT '.PER_PAGE), false) or error('Unable to select from old table', __FILE__, __LINE__, $db->error()); - - // Change back to utf8 mode so we can insert it into the new table - $db->set_names('utf8'); - - while ($cur_item = $db->fetch_assoc($result)) - { - $cur_item = call_user_func($callback, $cur_item, $old_charset); - - $temp = array(); - foreach ($cur_item as $idx => $value) - $temp[$idx] = $value === null ? 'NULL' : '\''.$db->escape($value).'\''; - - $db->query('INSERT INTO '.$table.'_utf8('.implode(',', array_keys($temp)).') VALUES ('.implode(',', array_values($temp)).')') or error('Unable to insert data to new table', __FILE__, __LINE__, $db->error()); - - $end_at = $cur_item[$key]; - } - - // If we aren't doing this all in 1 go and $end_at has a value (i.e. we have processed at least 1 row), figure out if we have more to do or not - if ($start_at !== null && $end_at > 0) - { - $result = $db->query('SELECT 1 FROM '.$table.' WHERE '.$key.'>'.$end_at.' ORDER BY '.$key.' ASC LIMIT 1') or error('Unable to check for next row', __FILE__, __LINE__, $db->error()); - $finished = $db->num_rows($result) == 0; - } - - // Only swap the tables if we are doing this in 1 go, or its the last go - if ($finished) - { - // Delete old table - $db->drop_table($table, true) or error('Unable to drop old table', __FILE__, __LINE__, $db->error()); - - // Rename table - $db->query('ALTER TABLE '.$table.'_utf8 RENAME '.$table) or error('Unable to rename new table', __FILE__, __LINE__, $db->error()); - - return true; - } - - return $end_at; - } - else - { - // Convert everything - $result = $db->query('SELECT * FROM '.$table.($start_at === null ? '' : ' WHERE '.$key.'>'.$start_at).' ORDER BY '.$key.' ASC'.($start_at === null ? '' : ' LIMIT '.PER_PAGE)) or error('Unable to select from table', __FILE__, __LINE__, $db->error()); - while ($cur_item = $db->fetch_assoc($result)) - { - $cur_item = call_user_func($callback, $cur_item, $old_charset); - - $temp = array(); - foreach ($cur_item as $idx => $value) - $temp[] = $idx.'='.($value === null ? 'NULL' : '\''.$db->escape($value).'\''); - - if (!empty($temp)) - $db->query('UPDATE '.$table.' SET '.implode(', ', $temp).' WHERE '.$key.'=\''.$db->escape($cur_item[$key]).'\'') or error('Unable to update data', __FILE__, __LINE__, $db->error()); - - $end_at = $cur_item[$key]; - } - - if ($start_at !== null && $end_at > 0) - { - $result = $db->query('SELECT 1 FROM '.$table.' WHERE '.$key.'>'.$end_at.' ORDER BY '.$key.' ASC LIMIT 1') or error('Unable to check for next row', __FILE__, __LINE__, $db->error()); - if ($db->num_rows($result) == 0) - return true; - - return $end_at; - } - - return true; - } -} - - -header('Content-type: text/html; charset=utf-8'); - -// Empty all output buffers and stop buffering -while (@ob_end_clean()); - - -$stage = isset($_GET['stage']) ? $_GET['stage'] : ''; -$old_charset = isset($_GET['req_old_charset']) ? str_replace('ISO8859', 'ISO-8859', strtoupper($_GET['req_old_charset'])) : 'ISO-8859-1'; -$start_at = isset($_GET['start_at']) ? intval($_GET['start_at']) : 0; -$query_str = ''; - -switch ($stage) -{ - // Show form - case '': - -?> - - - - - -FluxBB Database Update - - - - -
    -
    - -
    -

    FluxBB Update

    -
    -
    - -
    -

    This script will update your forum database. The update procedure might take anything from a second to hours depending on the speed of the server and the size of the forum database. Don't forget to make a backup of the database before continuing.

    -

    Did you read the update instructions in the documentation? If not, start there.

    - -

    IMPORTANT! FluxBB has detected that this PHP environment does not have support for the encoding mechanisms required to do UTF-8 conversion from character sets other than ISO-8859-1. What this means is that if the current character set is not ISO-8859-1, FluxBB won't be able to convert your forum database to UTF-8 and you will have to do it manually. Instructions for doing manual charset conversion can be found in the update instructions.

    - -
    -
    -

    Enable conversion: When enabled this update script will, after it has made the required structural changes to the database, convert all text in the database from the current character set to UTF-8. This conversion is required if you're upgrading from version 1.2.

    -

    Current character set: If the primary language in your forum is English, you can leave this at the default value. However, if your forum is non-English, you should enter the character set of the primary language pack used in the forum. Getting this wrong can corrupt your database so don't just guess! Note: This is required even if the old database is UTF-8.

    -
    - Charset conversion -
    - - - - - - - - - -
    Enable conversion: - - Perform database charset conversion. -
    Current character set: -
    - Accept default for English forums otherwise the character set of the primary language pack. -
    -
    -
    - -
    -

    -
    -
    -
    - -
    -
    - - - -alter_field('bans', 'email', 'VARCHAR(80)', true) or error('Unable to alter email field', __FILE__, __LINE__, $db->error()); - $db->alter_field('posts', 'poster_email', 'VARCHAR(80)', true) or error('Unable to alter poster_email field', __FILE__, __LINE__, $db->error()); - $db->alter_field('users', 'email', 'VARCHAR(80)', false, '') or error('Unable to alter email field', __FILE__, __LINE__, $db->error()); - $db->alter_field('users', 'jabber', 'VARCHAR(80)', true) or error('Unable to alter jabber field', __FILE__, __LINE__, $db->error()); - $db->alter_field('users', 'msn', 'VARCHAR(80)', true) or error('Unable to alter msn field', __FILE__, __LINE__, $db->error()); - $db->alter_field('users', 'activate_string', 'VARCHAR(80)', true) or error('Unable to alter activate_string field', __FILE__, __LINE__, $db->error()); - - // Make all IP fields VARCHAR(39) to support IPv6 - $db->alter_field('posts', 'poster_ip', 'VARCHAR(39)', true) or error('Unable to alter poster_ip field', __FILE__, __LINE__, $db->error()); - $db->alter_field('users', 'registration_ip', 'VARCHAR(39)', false, '0.0.0.0') or error('Unable to alter registration_ip field', __FILE__, __LINE__, $db->error()); - - // Add the DST option to the users table - $db->add_field('users', 'dst', 'TINYINT(1)', false, 0, 'timezone') or error('Unable to add dst field', __FILE__, __LINE__, $db->error()); - - // Add the last_post field to the online table - $db->add_field('online', 'last_post', 'INT(10) UNSIGNED', true, null, null) or error('Unable to add last_post field', __FILE__, __LINE__, $db->error()); - - // Add the last_search field to the online table - $db->add_field('online', 'last_search', 'INT(10) UNSIGNED', true, null, null) or error('Unable to add last_search field', __FILE__, __LINE__, $db->error()); - - // Add the last_search column to the users table - $db->add_field('users', 'last_search', 'INT(10) UNSIGNED', true, null, 'last_post') or error('Unable to add last_search field', __FILE__, __LINE__, $db->error()); - - // Drop use_avatar column from users table - $db->drop_field('users', 'use_avatar') or error('Unable to drop use_avatar field', __FILE__, __LINE__, $db->error()); - - // Drop save_pass column from users table - $db->drop_field('users', 'save_pass') or error('Unable to drop save_pass field', __FILE__, __LINE__, $db->error()); - - // Drop g_edit_subjects_interval column from groups table - $db->drop_field('groups', 'g_edit_subjects_interval'); - - // Add database revision number - if (!array_key_exists('o_database_revision', $pun_config)) - $db->query('INSERT INTO '.$db->prefix.'config (conf_name, conf_value) VALUES (\'o_database_revision\', \'0\')') or error('Unable to insert config value \'o_database_revision\'', __FILE__, __LINE__, $db->error()); - - // Add default email setting option - if (!array_key_exists('o_default_email_setting', $pun_config)) - $db->query('INSERT INTO '.$db->prefix.'config (conf_name, conf_value) VALUES (\'o_default_email_setting\', \'1\')') or error('Unable to insert config value \'o_default_email_setting\'', __FILE__, __LINE__, $db->error()); - - // Make sure we have o_additional_navlinks (was added in 1.2.1) - if (!array_key_exists('o_additional_navlinks', $pun_config)) - $db->query('INSERT INTO '.$db->prefix.'config (conf_name, conf_value) VALUES (\'o_additional_navlinks\', \'\')') or error('Unable to insert config value \'o_additional_navlinks\'', __FILE__, __LINE__, $db->error()); - - // Insert new config option o_topic_views - if (!array_key_exists('o_topic_views', $pun_config)) - $db->query('INSERT INTO '.$db->prefix.'config (conf_name, conf_value) VALUES (\'o_topic_views\', \'1\')') or error('Unable to insert config value \'o_topic_views\'', __FILE__, __LINE__, $db->error()); - - // Insert new config option o_signatures - if (!array_key_exists('o_signatures', $pun_config)) - $db->query('INSERT INTO '.$db->prefix.'config (conf_name, conf_value) VALUES (\'o_signatures\', \'1\')') or error('Unable to insert config value \'o_signatures\'', __FILE__, __LINE__, $db->error()); - - // Insert new config option o_smtp_ssl - if (!array_key_exists('o_smtp_ssl', $pun_config)) - $db->query('INSERT INTO '.$db->prefix.'config (conf_name, conf_value) VALUES (\'o_smtp_ssl\', \'0\')') or error('Unable to insert config value \'o_smtp_ssl\'', __FILE__, __LINE__, $db->error()); - - // Insert new config option o_default_dst - if (!array_key_exists('o_default_dst', $pun_config)) - $db->query('INSERT INTO '.$db->prefix.'config (conf_name, conf_value) VALUES (\'o_default_dst\', \'0\')') or error('Unable to insert config value \'o_default_dst\'', __FILE__, __LINE__, $db->error()); - - // Insert new config option o_quote_depth - if (!array_key_exists('o_quote_depth', $pun_config)) - $db->query('INSERT INTO '.$db->prefix.'config (conf_name, conf_value) VALUES (\'o_quote_depth\', \'3\')') or error('Unable to insert config value \'o_quote_depth\'', __FILE__, __LINE__, $db->error()); - - // Insert new config option o_feed_type - if (!array_key_exists('o_feed_type', $pun_config)) - $db->query('INSERT INTO '.$db->prefix.'config (conf_name, conf_value) VALUES (\'o_feed_type\', \'2\')') or error('Unable to insert config value \'o_feed_type\'', __FILE__, __LINE__, $db->error()); - - // Insert config option o_base_url which was removed in 1.3 - if (!array_key_exists('o_base_url', $pun_config)) - { - // If it isn't in $pun_config['o_base_url'] it should be in $base_url, but just in-case it isn't we can make a guess at it - if (!isset($base_url)) - { - // Make an educated guess regarding base_url - $base_url = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') ? 'https://' : 'http://'; // protocol - $base_url .= preg_replace('/:(80|443)$/', '', $_SERVER['HTTP_HOST']); // host[:port] - $base_url .= str_replace('\\', '/', dirname($_SERVER['SCRIPT_NAME'])); // path - } - - if (substr($base_url, -1) == '/') - $base_url = substr($base_url, 0, -1); - - $db->query('INSERT INTO '.$db->prefix.'config (conf_name, conf_value) VALUES (\'o_base_url\', \''.$db->escape($base_url).'\')') or error('Unable to insert config value \'o_quote_depth\'', __FILE__, __LINE__, $db->error()); - } - - if (strpos($cur_version, '1.2') === 0) - { - // Groups are almost the same as 1.2: - // unverified: 32000 -> 0 - - $db->query('UPDATE '.$db->prefix.'users SET group_id = 0 WHERE group_id = 32000') or error('Unable to update unverified users', __FILE__, __LINE__, $db->error()); - } - else if (strpos($cur_version, '1.3') === 0) - { - // Groups have changed quite a lot from 1.3: - // unverified: 0 -> 0 - // admin: 1 -> 1 - // mod: ? -> 2 - // guest: 2 -> 3 - // member: ? -> 4 - - $result = $db->query('SELECT MAX(g_id) + 1 FROM '.$db->prefix.'groups') or error('Unable to select temp group ID', __FILE__, __LINE__, $db->error()); - $temp_id = $db->result($result); - - $result = $db->query('SELECT g_id FROM '.$db->prefix.'groups WHERE g_moderator = 1 AND g_id > 1 LIMIT 1') or error('Unable to select moderator group', __FILE__, __LINE__, $db->error()); - if ($db->num_rows($result)) - $mod_gid = $db->result($result); - else - { - $db->query('INSERT INTO '.$db->prefix.'groups (g_title, g_user_title, g_moderator, g_mod_edit_users, g_mod_rename_users, g_mod_change_passwords, g_mod_ban_users, g_read_board, g_view_users, g_post_replies, g_post_topics, g_edit_posts, g_delete_posts, g_delete_topics, g_set_title, g_search, g_search_users, g_send_email, g_post_flood, g_search_flood, g_email_flood) VALUES('."'Moderators', 'Moderator', 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0)") or error('Unable to add group', __FILE__, __LINE__, $db->error()); - $mod_gid = $db->insert_id(); - } - - $member_gid = $pun_config['o_default_user_group']; - - // move the mod group to a temp place - $db->query('UPDATE '.$db->prefix.'groups SET g_id = '.$temp_id.' WHERE g_id = '.$mod_gid) or error('Unable to update group ID', __FILE__, __LINE__, $db->error()); - $db->query('UPDATE '.$db->prefix.'users SET group_id = '.$temp_id.' WHERE group_id = '.$mod_gid) or error('Unable to update users group ID', __FILE__, __LINE__, $db->error()); - $db->query('UPDATE '.$db->prefix.'forum_perms SET group_id = '.$temp_id.' WHERE group_id = '.$mod_gid) or error('Unable to forum_perms group ID', __FILE__, __LINE__, $db->error()); - if ($member_gid == $mod_gid) $member_gid = $temp_id; - - // move whoever is in 3 to a spare slot - $db->query('UPDATE '.$db->prefix.'groups SET g_id = '.$mod_gid.' WHERE g_id = 3') or error('Unable to update group ID', __FILE__, __LINE__, $db->error()); - $db->query('UPDATE '.$db->prefix.'users SET group_id = '.$mod_gid.' WHERE group_id = 3') or error('Unable to update users group ID', __FILE__, __LINE__, $db->error()); - $db->query('UPDATE '.$db->prefix.'forum_perms SET group_id = '.$mod_gid.' WHERE group_id = 3') or error('Unable to forum_perms group ID', __FILE__, __LINE__, $db->error()); - if ($member_gid == 3) $member_gid = $mod_gid; - - // move guest to 3 - $db->query('UPDATE '.$db->prefix.'groups SET g_id = 3 WHERE g_id = 2') or error('Unable to update group ID', __FILE__, __LINE__, $db->error()); - $db->query('UPDATE '.$db->prefix.'users SET group_id = 3 WHERE group_id = 2') or error('Unable to update users group ID', __FILE__, __LINE__, $db->error()); - $db->query('UPDATE '.$db->prefix.'forum_perms SET group_id = 3 WHERE group_id = 2') or error('Unable to forum_perms group ID', __FILE__, __LINE__, $db->error()); - if ($member_gid == 2) $member_gid = 3; - - // move mod group in temp place to 2 - $db->query('UPDATE '.$db->prefix.'groups SET g_id = 2 WHERE g_id = '.$temp_id) or error('Unable to update group ID', __FILE__, __LINE__, $db->error()); - $db->query('UPDATE '.$db->prefix.'users SET group_id = 2 WHERE group_id = '.$temp_id) or error('Unable to update users group ID', __FILE__, __LINE__, $db->error()); - $db->query('UPDATE '.$db->prefix.'forum_perms SET group_id = 2 WHERE group_id = '.$temp_id) or error('Unable to forum_perms group ID', __FILE__, __LINE__, $db->error()); - if ($member_gid == $temp_id) $member_gid = 2; - - // Only move stuff around if it isn't already in the right place - if ($member_gid != $mod_gid || $member_gid != 4) - { - // move members to temp place - $db->query('UPDATE '.$db->prefix.'groups SET g_id = '.$temp_id.' WHERE g_id = '.$member_gid) or error('Unable to update group ID', __FILE__, __LINE__, $db->error()); - $db->query('UPDATE '.$db->prefix.'users SET group_id = '.$temp_id.' WHERE group_id = '.$member_gid) or error('Unable to update users group ID', __FILE__, __LINE__, $db->error()); - $db->query('UPDATE '.$db->prefix.'forum_perms SET group_id = '.$temp_id.' WHERE group_id = '.$member_gid) or error('Unable to forum_perms group ID', __FILE__, __LINE__, $db->error()); - - // move whoever is in 4 to members place - $db->query('UPDATE '.$db->prefix.'groups SET g_id = '.$member_gid.' WHERE g_id = 4') or error('Unable to update group ID', __FILE__, __LINE__, $db->error()); - $db->query('UPDATE '.$db->prefix.'users SET group_id = '.$member_gid.' WHERE group_id = 4') or error('Unable to update users group ID', __FILE__, __LINE__, $db->error()); - $db->query('UPDATE '.$db->prefix.'forum_perms SET group_id = '.$member_gid.' WHERE group_id = 4') or error('Unable to forum_perms group ID', __FILE__, __LINE__, $db->error()); - - // move members in temp place to 4 - $db->query('UPDATE '.$db->prefix.'groups SET g_id = 4 WHERE g_id = '.$temp_id) or error('Unable to update group ID', __FILE__, __LINE__, $db->error()); - $db->query('UPDATE '.$db->prefix.'users SET group_id = 4 WHERE group_id = '.$temp_id) or error('Unable to update users group ID', __FILE__, __LINE__, $db->error()); - $db->query('UPDATE '.$db->prefix.'forum_perms SET group_id = 4 WHERE group_id = '.$temp_id) or error('Unable to forum_perms group ID', __FILE__, __LINE__, $db->error()); - } - } - - // Server time zone is now simply the default time zone - if (!array_key_exists('o_default_timezone', $pun_config)) - $db->query('UPDATE '.$db->prefix.'config SET conf_name = \'o_default_timezone\' WHERE conf_name = \'o_server_timezone\'') or error('Unable to update time zone config', __FILE__, __LINE__, $db->error()); - - // Increase visit timeout to 30 minutes (only if it hasn't been changed from the default) - if (!array_key_exists('o_database_revision', $pun_config) && $pun_config['o_timeout_visit'] == '600') - $db->query('UPDATE '.$db->prefix.'config SET conf_value = \'1800\' WHERE conf_name = \'o_timeout_visit\'') or error('Unable to update visit timeout config', __FILE__, __LINE__, $db->error()); - - // Remove obsolete g_post_polls permission from groups table - $db->drop_field('groups', 'g_post_polls'); - - // Make room for multiple moderator groups - if (!$db->field_exists('groups', 'g_moderator')) - { - // Add g_moderator column to groups table - $db->add_field('groups', 'g_moderator', 'TINYINT(1)', false, 0, 'g_user_title') or error('Unable to add g_moderator field', __FILE__, __LINE__, $db->error()); - - // Give the moderator group moderator privileges - $db->query('UPDATE '.$db->prefix.'groups SET g_moderator = 1 WHERE g_id = 2') or error('Unable to update moderator powers', __FILE__, __LINE__, $db->error()); - } - - // Replace obsolete p_mod_edit_users config setting with new per-group permission - if (array_key_exists('p_mod_edit_users', $pun_config)) - { - $db->query('DELETE FROM '.$db->prefix.'config WHERE conf_name = \'p_mod_edit_users\'') or error('Unable to update moderator powers', __FILE__, __LINE__, $db->error()); - - $db->add_field('groups', 'g_mod_edit_users', 'TINYINT(1)', false, 0, 'g_moderator') or error('Unable to add g_mod_edit_users field', __FILE__, __LINE__, $db->error()); - - $db->query('UPDATE '.$db->prefix.'groups SET g_mod_edit_users = '.$pun_config['p_mod_edit_users'].' WHERE g_moderator = 1') or error('Unable to update moderator powers', __FILE__, __LINE__, $db->error()); - } - - // Replace obsolete p_mod_rename_users config setting with new per-group permission - if (array_key_exists('p_mod_rename_users', $pun_config)) - { - $db->query('DELETE FROM '.$db->prefix.'config WHERE conf_name = \'p_mod_rename_users\'') or error('Unable to update moderator powers', __FILE__, __LINE__, $db->error()); - - $db->add_field('groups', 'g_mod_rename_users', 'TINYINT(1)', false, 0, 'g_mod_edit_users') or error('Unable to add g_mod_rename_users field', __FILE__, __LINE__, $db->error()); - - $db->query('UPDATE '.$db->prefix.'groups SET g_mod_rename_users = '.$pun_config['p_mod_rename_users'].' WHERE g_moderator = 1') or error('Unable to update moderator powers', __FILE__, __LINE__, $db->error()); - } - - // Replace obsolete p_mod_change_passwords config setting with new per-group permission - if (array_key_exists('p_mod_change_passwords', $pun_config)) - { - $db->query('DELETE FROM '.$db->prefix.'config WHERE conf_name = \'p_mod_change_passwords\'') or error('Unable to update moderator powers', __FILE__, __LINE__, $db->error()); - - $db->add_field('groups', 'g_mod_change_passwords', 'TINYINT(1)', false, 0, 'g_mod_rename_users') or error('Unable to add g_mod_change_passwords field', __FILE__, __LINE__, $db->error()); - - $db->query('UPDATE '.$db->prefix.'groups SET g_mod_change_passwords = '.$pun_config['p_mod_change_passwords'].' WHERE g_moderator = 1') or error('Unable to update moderator powers', __FILE__, __LINE__, $db->error()); - } - - // Replace obsolete p_mod_ban_users config setting with new per-group permission - if (array_key_exists('p_mod_ban_users', $pun_config)) - { - $db->query('DELETE FROM '.$db->prefix.'config WHERE conf_name = \'p_mod_ban_users\'') or error('Unable to update moderator powers', __FILE__, __LINE__, $db->error()); - - $db->add_field('groups', 'g_mod_ban_users', 'TINYINT(1)', false, 0, 'g_mod_change_passwords') or error('Unable to add g_mod_ban_users field', __FILE__, __LINE__, $db->error()); - - $db->query('UPDATE '.$db->prefix.'groups SET g_mod_ban_users = '.$pun_config['p_mod_ban_users'].' WHERE g_moderator = 1') or error('Unable to update moderator powers', __FILE__, __LINE__, $db->error()); - } - - // We need to add a unique index to avoid users having multiple rows in the online table - if (!$db->index_exists('online', 'user_id_ident_idx')) - { - $db->truncate_table('online') or error('Unable to clear online table', __FILE__, __LINE__, $db->error()); - - if ($mysql) - $db->add_index('online', 'user_id_ident_idx', array('user_id', 'ident(25)'), true) or error('Unable to add user_id_ident_idx index', __FILE__, __LINE__, $db->error()); - else - $db->add_index('online', 'user_id_ident_idx', array('user_id', 'ident'), true) or error('Unable to add user_id_ident_idx index', __FILE__, __LINE__, $db->error()); - } - - // Remove the redundant user_id_idx on the online table - $db->drop_index('online', 'user_id_idx') or error('Unable to drop user_id_idx index', __FILE__, __LINE__, $db->error()); - - // Add an index to ident on the online table - if ($mysql) - $db->add_index('online', 'ident_idx', array('ident(25)')) or error('Unable to add ident_idx index', __FILE__, __LINE__, $db->error()); - else - $db->add_index('online', 'ident_idx', array('ident')) or error('Unable to add ident_idx index', __FILE__, __LINE__, $db->error()); - - // Add an index to logged in the online table - $db->add_index('online', 'logged_idx', array('logged')) or error('Unable to add logged_idx index', __FILE__, __LINE__, $db->error()); - - // Add an index to last_post in the topics table - $db->add_index('topics', 'last_post_idx', array('last_post')) or error('Unable to add last_post_idx index', __FILE__, __LINE__, $db->error()); - - // Add an index to username on the bans table - if ($mysql) - $db->add_index('bans', 'username_idx', array('username(25)')) or error('Unable to add username_idx index', __FILE__, __LINE__, $db->error()); - else - $db->add_index('bans', 'username_idx', array('username')) or error('Unable to add username_idx index', __FILE__, __LINE__, $db->error()); - - // Change the username_idx on users to a unique index of max size 25 - $db->drop_index('users', 'username_idx') or error('Unable to drop old username_idx index', __FILE__, __LINE__, $db->error()); - $field = $mysql ? 'username(25)' : 'username'; - - // Attempt to add a unique index. If the user doesn't use a transactional database this can fail due to multiple matching usernames in the - // users table. This is bad, but just giving up if it happens is even worse! If it fails just add a regular non-unique index. - if (!$db->add_index('users', 'username_idx', array($field), true)) - $db->add_index('users', 'username_idx', array($field)) or error('Unable to add username_idx field', __FILE__, __LINE__, $db->error()); - - // Add g_view_users field to groups table - $db->add_field('groups', 'g_view_users', 'TINYINT(1)', false, 1, 'g_read_board') or error('Unable to add g_view_users field', __FILE__, __LINE__, $db->error()); - - // Add the last_email_sent column to the users table and the g_send_email and - // g_email_flood columns to the groups table - $db->add_field('users', 'last_email_sent', 'INT(10) UNSIGNED', true, null, 'last_search') or error('Unable to add last_email_sent field', __FILE__, __LINE__, $db->error()); - $db->add_field('groups', 'g_send_email', 'TINYINT(1)', false, 1, 'g_search_users') or error('Unable to add g_send_email field', __FILE__, __LINE__, $db->error()); - $db->add_field('groups', 'g_email_flood', 'SMALLINT(6)', false, 60, 'g_search_flood') or error('Unable to add g_email_flood field', __FILE__, __LINE__, $db->error()); - - // Set non-default g_send_email and g_flood_email values properly - $db->query('UPDATE '.$db->prefix.'groups SET g_send_email = 0 WHERE g_id = 3') or error('Unable to update group email permissions', __FILE__, __LINE__, $db->error()); - $db->query('UPDATE '.$db->prefix.'groups SET g_email_flood = 0 WHERE g_id IN (1,2,3)') or error('Unable to update group email permissions', __FILE__, __LINE__, $db->error()); - - // Add the auto notify/subscription option to the users table - $db->add_field('users', 'auto_notify', 'TINYINT(1)', false, 0, 'notify_with_post') or error('Unable to add auto_notify field', __FILE__, __LINE__, $db->error()); - - // Add the first_post_id column to the topics table - if (!$db->field_exists('topics', 'first_post_id')) - { - $db->add_field('topics', 'first_post_id', 'INT(10) UNSIGNED', false, 0, 'posted') or error('Unable to add first_post_id field', __FILE__, __LINE__, $db->error()); - $db->add_index('topics', 'first_post_id_idx', array('first_post_id')) or error('Unable to add first_post_id_idx index', __FILE__, __LINE__, $db->error()); - - // Now that we've added the column and indexed it, we need to give it correct data - $result = $db->query('SELECT MIN(id) AS first_post, topic_id FROM '.$db->prefix.'posts GROUP BY topic_id') or error('Unable to fetch first_post_id', __FILE__, __LINE__, $db->error()); - - while ($cur_post = $db->fetch_assoc($result)) - $db->query('UPDATE '.$db->prefix.'topics SET first_post_id = '.$cur_post['first_post'].' WHERE id = '.$cur_post['topic_id']) or error('Unable to update first_post_id', __FILE__, __LINE__, $db->error()); - } - - // Move any users with the old unverified status to their new group - $db->query('UPDATE '.$db->prefix.'users SET group_id=0 WHERE group_id=32000') or error('Unable to move unverified users', __FILE__, __LINE__, $db->error()); - - // Add the ban_creator column to the bans table - $db->add_field('bans', 'ban_creator', 'INT(10) UNSIGNED', false, 0) or error('Unable to add ban_creator field', __FILE__, __LINE__, $db->error()); - - // Add the time/date format settings to the user table - $db->add_field('users', 'time_format', 'TINYINT(1)', false, 0, 'dst') or error('Unable to add time_format field', __FILE__, __LINE__, $db->error()); - $db->add_field('users', 'date_format', 'TINYINT(1)', false, 0, 'dst') or error('Unable to add date_format field', __FILE__, __LINE__, $db->error()); - - // Change the search_data field to mediumtext - $db->alter_field('search_cache', 'search_data', 'MEDIUMTEXT', true) or error('Unable to alter search_data field', __FILE__, __LINE__, $db->error()); - - // Incase we had the fulltext search extension installed (1.3-legacy), remove it - $db->drop_index('topics', 'subject_idx') or error('Unable to drop subject_idx index', __FILE__, __LINE__, $db->error()); - $db->drop_index('posts', 'message_idx') or error('Unable to drop message_idx index', __FILE__, __LINE__, $db->error()); - - // If the search_cache table has been dropped by the fulltext search extension, recreate it - if (!$db->table_exists('search_cache')) - { - $schema = array( - 'FIELDS' => array( - 'id' => array( - 'datatype' => 'INT(10) UNSIGNED', - 'allow_null' => false, - 'default' => '0' - ), - 'ident' => array( - 'datatype' => 'VARCHAR(200)', - 'allow_null' => false, - 'default' => '\'\'' - ), - 'search_data' => array( - 'datatype' => 'MEDIUMTEXT', - 'allow_null' => true - ) - ), - 'PRIMARY KEY' => array('id'), - 'INDEXES' => array( - 'ident_idx' => array('ident') - ) - ); - - if ($db_type == 'mysql' || $db_type == 'mysqli' || $db_type == 'mysql_innodb' || $db_type == 'mysqli_innodb') - $schema['INDEXES']['ident_idx'] = array('ident(8)'); - - $db->create_table('search_cache', $schema); - } - - // If the search_matches table has been dropped by the fulltext search extension, recreate it - if (!$db->table_exists('search_matches')) - { - $schema = array( - 'FIELDS' => array( - 'post_id' => array( - 'datatype' => 'INT(10) UNSIGNED', - 'allow_null' => false, - 'default' => '0' - ), - 'word_id' => array( - 'datatype' => 'INT(10) UNSIGNED', - 'allow_null' => false, - 'default' => '0' - ), - 'subject_match' => array( - 'datatype' => 'TINYINT(1)', - 'allow_null' => false, - 'default' => '0' - ) - ), - 'INDEXES' => array( - 'word_id_idx' => array('word_id'), - 'post_id_idx' => array('post_id') - ) - ); - - $db->create_table('search_matches', $schema); - } - - // If the search_words table has been dropped by the fulltext search extension, recreate it - if (!$db->table_exists('search_words')) - { - $schema = array( - 'FIELDS' => array( - 'id' => array( - 'datatype' => 'SERIAL', - 'allow_null' => false - ), - 'word' => array( - 'datatype' => 'VARCHAR(20)', - 'allow_null' => false, - 'default' => '\'\'', - 'collation' => 'bin' - ) - ), - 'PRIMARY KEY' => array('word'), - 'INDEXES' => array( - 'id_idx' => array('id') - ) - ); - - if ($db_type == 'sqlite') - { - $schema['PRIMARY KEY'] = array('id'); - $schema['UNIQUE KEYS'] = array('word_idx' => array('word')); - } - - $db->create_table('search_words', $schema); - } - - // Change the default style if the old doesn't exist anymore - if ($pun_config['o_default_style'] != $default_style) - $db->query('UPDATE '.$db->prefix.'config SET conf_value = \''.$db->escape($default_style).'\' WHERE conf_name = \'o_default_style\'') or error('Unable to update default style config', __FILE__, __LINE__, $db->error()); - - // Should we do charset conversion or not? - if (strpos($cur_version, '1.2') === 0 && isset($_GET['convert_charset'])) - $query_str = '?stage=conv_bans&req_old_charset='.$old_charset; - - break; - - - // Convert bans - case 'conv_bans': - $query_str = '?stage=conv_categories&req_old_charset='.$old_charset; - - function _conv_bans($cur_item, $old_charset) - { - echo 'Converting ban '.$cur_item['id'].' …
    '."\n"; - - convert_to_utf8($cur_item['username'], $old_charset); - convert_to_utf8($cur_item['message'], $old_charset); - - return $cur_item; - } - - $end_at = convert_table_utf8($db->prefix.'bans', '_conv_bans', $old_charset, 'id', $start_at); - - if ($end_at !== true) - $query_str = '?stage=conv_bans&req_old_charset='.$old_charset.'&start_at='.$end_at; - - break; - - - // Convert categories - case 'conv_categories': - $query_str = '?stage=conv_censors&req_old_charset='.$old_charset; - - echo 'Converting categories …'."
    \n"; - - function _conv_categories($cur_item, $old_charset) - { - convert_to_utf8($cur_item['cat_name'], $old_charset); - - return $cur_item; - } - - convert_table_utf8($db->prefix.'categories', '_conv_categories', $old_charset, 'id'); - - break; - - - // Convert censor words - case 'conv_censors': - $query_str = '?stage=conv_config&req_old_charset='.$old_charset; - - echo 'Converting censor words …'."
    \n"; - - function _conv_censoring($cur_item, $old_charset) - { - convert_to_utf8($cur_item['search_for'], $old_charset); - convert_to_utf8($cur_item['replace_with'], $old_charset); - - return $cur_item; - } - - convert_table_utf8($db->prefix.'censoring', '_conv_censoring', $old_charset, 'id'); - - break; - - - // Convert config - case 'conv_config': - $query_str = '?stage=conv_forums&req_old_charset='.$old_charset; - - echo 'Converting configuration …'."
    \n"; - - function _conv_config($cur_item, $old_charset) - { - convert_to_utf8($cur_item['conf_value'], $old_charset); - - return $cur_item; - } - - convert_table_utf8($db->prefix.'config', '_conv_config', $old_charset, 'conf_name'); - - break; - - - // Convert forums - case 'conv_forums': - $query_str = '?stage=conv_perms&req_old_charset='.$old_charset; - - echo 'Converting forums …'."
    \n"; - - function _conv_forums($cur_item, $old_charset) - { - $moderators = ($cur_item['moderators'] != '') ? unserialize($cur_item['moderators']) : array(); - $moderators_utf8 = array(); - foreach ($moderators as $mod_username => $mod_user_id) - { - convert_to_utf8($mod_username, $old_charset); - $moderators_utf8[$mod_username] = $mod_user_id; - } - - convert_to_utf8($cur_item['forum_name'], $old_charset); - convert_to_utf8($cur_item['forum_desc'], $old_charset); - - if (!empty($moderators_utf8)) - $cur_item['moderators'] = serialize($moderators_utf8); - - return $cur_item; - } - - convert_table_utf8($db->prefix.'forums', '_conv_forums', $old_charset, 'id'); - - break; - - - // Convert forum permissions - case 'conv_perms': - $query_str = '?stage=conv_groups&req_old_charset='.$old_charset; - - alter_table_utf8($db->prefix.'forum_perms'); - - break; - - - // Convert groups - case 'conv_groups': - $query_str = '?stage=conv_online&req_old_charset='.$old_charset; - - echo 'Converting groups …'."
    \n"; - - function _conv_groups($cur_item, $old_charset) - { - convert_to_utf8($cur_item['g_title'], $old_charset); - convert_to_utf8($cur_item['g_user_title'], $old_charset); - - return $cur_item; - } - - convert_table_utf8($db->prefix.'groups', '_conv_groups', $old_charset, 'g_id'); - - break; - - - // Convert online - case 'conv_online': - $query_str = '?stage=conv_posts&req_old_charset='.$old_charset; - - // Truncate the table - $db->truncate_table('online') or error('Unable to empty online table', __FILE__, __LINE__, $db->error()); - - alter_table_utf8($db->prefix.'online'); - - break; - - - // Convert posts - case 'conv_posts': - $query_str = '?stage=conv_ranks&req_old_charset='.$old_charset; - - function _conv_posts($cur_item, $old_charset) - { - echo 'Converting post '.$cur_item['id'].' …
    '."\n"; - - convert_to_utf8($cur_item['poster'], $old_charset); - convert_to_utf8($cur_item['message'], $old_charset); - convert_to_utf8($cur_item['edited_by'], $old_charset); - - return $cur_item; - } - - $end_at = convert_table_utf8($db->prefix.'posts', '_conv_posts', $old_charset, 'id', $start_at); - - if ($end_at !== true) - $query_str = '?stage=conv_posts&req_old_charset='.$old_charset.'&start_at='.$end_at; - - break; - - - // Convert ranks - case 'conv_ranks': - $query_str = '?stage=conv_reports&req_old_charset='.$old_charset; - - echo 'Converting ranks …'."
    \n"; - - function _conv_ranks($cur_item, $old_charset) - { - convert_to_utf8($cur_item['rank'], $old_charset); - - return $cur_item; - } - - convert_table_utf8($db->prefix.'ranks', '_conv_ranks', $old_charset, 'id'); - - break; - - - // Convert reports - case 'conv_reports': - $query_str = '?stage=conv_search_cache&req_old_charset='.$old_charset; - - function _conv_reports($cur_item, $old_charset) - { - echo 'Converting report '.$cur_item['id'].' …
    '."\n"; - - convert_to_utf8($cur_item['message'], $old_charset); - - return $cur_item; - } - - $end_at = convert_table_utf8($db->prefix.'reports', '_conv_reports', $old_charset, 'id', $start_at); - - if ($end_at !== true) - $query_str = '?stage=conv_reports&req_old_charset='.$old_charset.'&start_at='.$end_at; - - break; - - - // Convert search cache - case 'conv_search_cache': - $query_str = '?stage=conv_search_matches&req_old_charset='.$old_charset; - - // Truncate the table - $db->truncate_table('search_cache') or error('Unable to empty search cache table', __FILE__, __LINE__, $db->error()); - - alter_table_utf8($db->prefix.'search_cache'); - - break; - - - // Convert search matches - case 'conv_search_matches': - $query_str = '?stage=conv_search_words&req_old_charset='.$old_charset; - - // Truncate the table - $db->truncate_table('search_matches') or error('Unable to empty search index match table', __FILE__, __LINE__, $db->error()); - - alter_table_utf8($db->prefix.'search_matches'); - - break; - - - // Convert search words - case 'conv_search_words': - $query_str = '?stage=conv_subscriptions&req_old_charset='.$old_charset; - - // Truncate the table - $db->truncate_table('search_words') or error('Unable to empty search index words table', __FILE__, __LINE__, $db->error()); - - // Reset the sequence for the search words (not needed for SQLite) - switch ($db_type) - { - case 'mysql': - case 'mysqli': - case 'mysql_innodb': - case 'mysqli_innodb': - $db->query('ALTER TABLE '.$db->prefix.'search_words auto_increment=1') or error('Unable to update table auto_increment', __FILE__, __LINE__, $db->error()); - break; - - case 'pgsql'; - $db->query('SELECT setval(\''.$db->prefix.'search_words_id_seq\', 1, false)') or error('Unable to update sequence', __FILE__, __LINE__, $db->error()); - break; - } - - alter_table_utf8($db->prefix.'search_words'); - - break; - - - // Convert subscriptions - case 'conv_subscriptions': - $query_str = '?stage=conv_topics&req_old_charset='.$old_charset; - - alter_table_utf8($db->prefix.'subscriptions'); - - break; - - - // Convert topics - case 'conv_topics': - $query_str = '?stage=conv_users&req_old_charset='.$old_charset; - - function _conv_topics($cur_item, $old_charset) - { - echo 'Converting topic '.$cur_item['id'].' …
    '."\n"; - - convert_to_utf8($cur_item['poster'], $old_charset); - convert_to_utf8($cur_item['subject'], $old_charset); - convert_to_utf8($cur_item['last_poster'], $old_charset); - - return $cur_item; - } - - $end_at = convert_table_utf8($db->prefix.'topics', '_conv_topics', $old_charset, 'id', $start_at); - - if ($end_at !== true) - $query_str = '?stage=conv_topics&req_old_charset='.$old_charset.'&start_at='.$end_at; - - break; - - - // Convert users - case 'conv_users': - $query_str = '?stage=preparse_posts'; - - function _conv_users($cur_item, $old_charset) - { - echo 'Converting user '.$cur_item['id'].' …
    '."\n"; - - convert_to_utf8($cur_item['username'], $old_charset); - convert_to_utf8($cur_item['title'], $old_charset); - convert_to_utf8($cur_item['realname'], $old_charset); - convert_to_utf8($cur_item['location'], $old_charset); - convert_to_utf8($cur_item['signature'], $old_charset); - convert_to_utf8($cur_item['admin_note'], $old_charset); - - return $cur_item; - } - - $end_at = convert_table_utf8($db->prefix.'users', '_conv_users', $old_charset, 'id', $start_at); - - if ($end_at !== true) - $query_str = '?stage=conv_users&req_old_charset='.$old_charset.'&start_at='.$end_at; - - break; - - - // Check if we need to do any more work - case 'pre_finish': - $query_str = '?stage=finish'; - - // If we are doing a major update we should preparse the posts and reindex everything - if (strpos($cur_version, substr(UPDATE_TO, 0, 3)) !== 0) - $query_str = '?stage=preparse_posts'; - - break; - - - // Preparse posts - case 'preparse_posts': - $query_str = '?stage=preparse_sigs'; - - require PUN_ROOT.'include/parser.php'; - - // Fetch posts to process this cycle - $result = $db->query('SELECT id, message FROM '.$db->prefix.'posts WHERE id > '.$start_at.' ORDER BY id ASC LIMIT '.PER_PAGE) or error('Unable to fetch posts', __FILE__, __LINE__, $db->error()); - - $temp = array(); - $end_at = 0; - while ($cur_item = $db->fetch_assoc($result)) - { - echo 'Preparsing post '.$cur_item['id'].' …
    '."\n"; - $db->query('UPDATE '.$db->prefix.'posts SET message = \''.$db->escape(preparse_bbcode($cur_item['message'], $temp)).'\' WHERE id = '.$cur_item['id']) or error('Unable to update post', __FILE__, __LINE__, $db->error()); - - $end_at = $cur_item['id']; - } - - // Check if there is more work to do - if ($end_at > 0) - { - $result = $db->query('SELECT 1 FROM '.$db->prefix.'posts WHERE id > '.$end_at.' ORDER BY id ASC LIMIT 1') or error('Unable to fetch next ID', __FILE__, __LINE__, $db->error()); - - if ($db->num_rows($result) > 0) - $query_str = '?stage=preparse_posts&start_at='.$end_at; - } - - break; - - - // Preparse signatures - case 'preparse_sigs': - $query_str = '?stage=rebuild_idx'; - - require PUN_ROOT.'include/parser.php'; - - // Fetch users to process this cycle - $result = $db->query('SELECT id, signature FROM '.$db->prefix.'users WHERE id > '.$start_at.' ORDER BY id ASC LIMIT '.PER_PAGE) or error('Unable to fetch users', __FILE__, __LINE__, $db->error()); - - $temp = array(); - $end_at = 0; - while ($cur_item = $db->fetch_assoc($result)) - { - echo 'Preparsing signature '.$cur_item['id'].' …
    '."\n"; - $db->query('UPDATE '.$db->prefix.'users SET signature = \''.$db->escape(preparse_bbcode($cur_item['signature'], $temp, true)).'\' WHERE id = '.$cur_item['id']) or error('Unable to update user', __FILE__, __LINE__, $db->error()); - - $end_at = $cur_item['id']; - } - - // Check if there is more work to do - if ($end_at > 0) - { - $result = $db->query('SELECT 1 FROM '.$db->prefix.'users WHERE id > '.$end_at.' ORDER BY id ASC LIMIT 1') or error('Unable to fetch next ID', __FILE__, __LINE__, $db->error()); - if ($db->num_rows($result) > 0) - $query_str = '?stage=preparse_sigs&start_at='.$end_at; - } - - break; - - - // Rebuild the search index - case 'rebuild_idx': - $query_str = '?stage=finish'; - - if ($start_at == 0) - { - // Truncate the tables just in-case we didn't already (if we are coming directly here without converting the tables) - $db->truncate_table('search_cache') or error('Unable to empty search cache table', __FILE__, __LINE__, $db->error()); - $db->truncate_table('search_matches') or error('Unable to empty search index match table', __FILE__, __LINE__, $db->error()); - $db->truncate_table('search_words') or error('Unable to empty search index words table', __FILE__, __LINE__, $db->error()); - - // Reset the sequence for the search words (not needed for SQLite) - switch ($db_type) - { - case 'mysql': - case 'mysqli': - case 'mysql_innodb': - case 'mysqli_innodb': - $db->query('ALTER TABLE '.$db->prefix.'search_words auto_increment=1') or error('Unable to update table auto_increment', __FILE__, __LINE__, $db->error()); - break; - - case 'pgsql'; - $db->query('SELECT setval(\''.$db->prefix.'search_words_id_seq\', 1, false)') or error('Unable to update sequence', __FILE__, __LINE__, $db->error()); - break; - } - } - - require PUN_ROOT.'include/search_idx.php'; - - // Fetch posts to process this cycle - $result = $db->query('SELECT p.id, p.message, t.subject, t.first_post_id FROM '.$db->prefix.'posts AS p INNER JOIN '.$db->prefix.'topics AS t ON t.id=p.topic_id WHERE p.id > '.$start_at.' ORDER BY p.id ASC LIMIT '.PER_PAGE) or error('Unable to fetch posts', __FILE__, __LINE__, $db->error()); - - $end_at = 0; - while ($cur_item = $db->fetch_assoc($result)) - { - echo 'Rebuilding index for post '.$cur_item['id'].' …
    '."\n"; - - if ($cur_item['id'] == $cur_item['first_post_id']) - update_search_index('post', $cur_item['id'], $cur_item['message'], $cur_item['subject']); - else - update_search_index('post', $cur_item['id'], $cur_item['message']); - - $end_at = $cur_item['id']; - } - - // Check if there is more work to do - if ($end_at > 0) - { - $result = $db->query('SELECT 1 FROM '.$db->prefix.'posts WHERE id > '.$end_at.' ORDER BY id ASC LIMIT 1') or error('Unable to fetch next ID', __FILE__, __LINE__, $db->error()); - - if ($db->num_rows($result) > 0) - $query_str = '?stage=rebuild_idx&start_at='.$end_at; - } - - break; - - - // Show results page - case 'finish': - // We update the version number - $db->query('UPDATE '.$db->prefix.'config SET conf_value = \''.UPDATE_TO.'\' WHERE conf_name = \'o_cur_version\'') or error('Unable to update version', __FILE__, __LINE__, $db->error()); - - // And the database revision number - $db->query('UPDATE '.$db->prefix.'config SET conf_value = \''.UPDATE_TO_DB_REVISION.'\' WHERE conf_name = \'o_database_revision\'') or error('Unable to update database revision number', __FILE__, __LINE__, $db->error()); - - // This feels like a good time to synchronize the forums - $result = $db->query('SELECT id FROM '.$db->prefix.'forums') or error('Unable to fetch forum IDs', __FILE__, __LINE__, $db->error()); - - while ($row = $db->fetch_row($result)) - update_forum($row[0]); - - // Empty the PHP cache - forum_clear_cache(); - -?> - - - - - -FluxBB Database Update - - - - -
    -
    - -
    -

    FluxBB Update

    -
    -
    -
    -

    Your forum database was successfully updated. You may now go to the forum index.

    -
    -
    -
    -
    - -
    -
    - - - -end_transaction(); -$db->close(); - -if ($query_str != '') - exit('
    JavaScript seems to be disabled. Click here to continue.'); diff --git a/upload/delete.php b/upload/delete.php deleted file mode 100644 index 69868ac..0000000 --- a/upload/delete.php +++ /dev/null @@ -1,111 +0,0 @@ -query('SELECT f.id AS fid, f.forum_name, f.moderators, f.redirect_url, fp.post_replies, fp.post_topics, t.id AS tid, t.subject, t.posted, t.first_post_id, t.closed, p.poster, p.poster_id, p.message, p.hide_smilies FROM '.$db->prefix.'posts AS p INNER JOIN '.$db->prefix.'topics AS t ON t.id=p.topic_id INNER JOIN '.$db->prefix.'forums AS f ON f.id=t.forum_id LEFT JOIN '.$db->prefix.'forum_perms AS fp ON (fp.forum_id=f.id AND fp.group_id='.$pun_user['g_id'].') WHERE (fp.read_forum IS NULL OR fp.read_forum=1) AND p.id='.$id) or error('Unable to fetch post info', __FILE__, __LINE__, $db->error()); -if (!$db->num_rows($result)) - message($lang_common['Bad request']); - -$cur_post = $db->fetch_assoc($result); - -// Sort out who the moderators are and if we are currently a moderator (or an admin) -$mods_array = ($cur_post['moderators'] != '') ? unserialize($cur_post['moderators']) : array(); -$is_admmod = ($pun_user['g_id'] == PUN_ADMIN || ($pun_user['g_moderator'] == '1' && array_key_exists($pun_user['username'], $mods_array))) ? true : false; - -$is_topic_post = ($id == $cur_post['first_post_id']) ? true : false; - -// Do we have permission to edit this post? -if (($pun_user['g_delete_posts'] == '0' || - ($pun_user['g_delete_topics'] == '0' && $is_topic_post) || - $cur_post['poster_id'] != $pun_user['id'] || - $cur_post['closed'] == '1') && - !$is_admmod) - message($lang_common['No permission']); - -// Load the delete.php language file -require PUN_ROOT.'lang/'.$pun_user['language'].'/delete.php'; - - -if (isset($_POST['delete'])) -{ - if ($is_admmod) - confirm_referrer('delete.php'); - - require PUN_ROOT.'include/search_idx.php'; - - if ($is_topic_post) - { - // Delete the topic and all of it's posts - delete_topic($cur_post['tid']); - update_forum($cur_post['fid']); - - redirect('viewforum.php?id='.$cur_post['fid'], $lang_delete['Topic del redirect']); - } - else - { - // Delete just this one post - delete_post($id, $cur_post['tid']); - update_forum($cur_post['fid']); - - redirect('viewtopic.php?id='.$cur_post['tid'], $lang_delete['Post del redirect']); - } -} - - -$page_title = array(pun_htmlspecialchars($pun_config['o_board_title']), $lang_delete['Delete post']); -define ('PUN_ACTIVE_PAGE', 'index'); -require PUN_ROOT.'header.php'; - -require PUN_ROOT.'include/parser.php'; -$cur_post['message'] = parse_message($cur_post['message'], $cur_post['hide_smilies']); - -?> -
    -
    -
      -
    • -
    • » 
    • -
    • » 
    • -
    • » 
    • -
    -
    -
    - -
    -

    -
    -
    -
    -

    -

    '.pun_htmlspecialchars($cur_post['poster'])) ?>

    -

    -
    -
    - -
    -
    -
    -

    - -
    -
    -query('SELECT f.id AS fid, f.forum_name, f.moderators, f.redirect_url, fp.post_replies, fp.post_topics, t.id AS tid, t.subject, t.posted, t.first_post_id, t.closed, p.poster, p.poster_id, p.message, p.hide_smilies FROM '.$db->prefix.'posts AS p INNER JOIN '.$db->prefix.'topics AS t ON t.id=p.topic_id INNER JOIN '.$db->prefix.'forums AS f ON f.id=t.forum_id LEFT JOIN '.$db->prefix.'forum_perms AS fp ON (fp.forum_id=f.id AND fp.group_id='.$pun_user['g_id'].') WHERE (fp.read_forum IS NULL OR fp.read_forum=1) AND p.id='.$id) or error('Unable to fetch post info', __FILE__, __LINE__, $db->error()); -if (!$db->num_rows($result)) - message($lang_common['Bad request']); - -$cur_post = $db->fetch_assoc($result); - -// Sort out who the moderators are and if we are currently a moderator (or an admin) -$mods_array = ($cur_post['moderators'] != '') ? unserialize($cur_post['moderators']) : array(); -$is_admmod = ($pun_user['g_id'] == PUN_ADMIN || ($pun_user['g_moderator'] == '1' && array_key_exists($pun_user['username'], $mods_array))) ? true : false; - -$can_edit_subject = $id == $cur_post['first_post_id']; - -// Do we have permission to edit this post? -if (($pun_user['g_edit_posts'] == '0' || - $cur_post['poster_id'] != $pun_user['id'] || - $cur_post['closed'] == '1') && - !$is_admmod) - message($lang_common['No permission']); - -// Load the post.php/edit.php language file -require PUN_ROOT.'lang/'.$pun_user['language'].'/post.php'; - -// Start with a clean slate -$errors = array(); - - -if (isset($_POST['form_sent'])) -{ - if ($is_admmod) - confirm_referrer('edit.php'); - - // If it's a topic it must contain a subject - if ($can_edit_subject) - { - $subject = pun_trim($_POST['req_subject']); - - if ($subject == '') - $errors[] = $lang_post['No subject']; - else if (pun_strlen($subject) > 70) - $errors[] = $lang_post['Too long subject']; - else if ($pun_config['p_subject_all_caps'] == '0' && is_all_uppercase($subject) && !$pun_user['is_admmod']) - $errors[] = $lang_post['All caps subject']; - } - - // Clean up message from POST - $message = pun_linebreaks(pun_trim($_POST['req_message'])); - - if (pun_strlen($message) > PUN_MAX_POSTSIZE) - $errors[] = $lang_post['Too long message']; - else if ($pun_config['p_message_all_caps'] == '0' && is_all_uppercase($message) && !$pun_user['is_admmod']) - $errors[] = $lang_post['All caps message']; - - // Validate BBCode syntax - if ($pun_config['p_message_bbcode'] == '1') - { - require PUN_ROOT.'include/parser.php'; - $message = preparse_bbcode($message, $errors); - } - - if ($message == '') - $errors[] = $lang_post['No message']; - - $hide_smilies = isset($_POST['hide_smilies']) ? '1' : '0'; - - // Did everything go according to plan? - if (empty($errors) && !isset($_POST['preview'])) - { - $edited_sql = (!isset($_POST['silent']) || !$is_admmod) ? $edited_sql = ', edited='.time().', edited_by=\''.$db->escape($pun_user['username']).'\'' : ''; - - require PUN_ROOT.'include/search_idx.php'; - - if ($can_edit_subject) - { - // Update the topic and any redirect topics - $db->query('UPDATE '.$db->prefix.'topics SET subject=\''.$db->escape($subject).'\' WHERE id='.$cur_post['tid'].' OR moved_to='.$cur_post['tid']) or error('Unable to update topic', __FILE__, __LINE__, $db->error()); - - // We changed the subject, so we need to take that into account when we update the search words - update_search_index('edit', $id, $message, $subject); - } - else - update_search_index('edit', $id, $message); - - // Update the post - $db->query('UPDATE '.$db->prefix.'posts SET message=\''.$db->escape($message).'\', hide_smilies='.$hide_smilies.$edited_sql.' WHERE id='.$id) or error('Unable to update post', __FILE__, __LINE__, $db->error()); - - redirect('viewtopic.php?pid='.$id.'#p'.$id, $lang_post['Edit redirect']); - } -} - - - -$page_title = array(pun_htmlspecialchars($pun_config['o_board_title']), $lang_post['Edit post']); -$required_fields = array('req_subject' => $lang_common['Subject'], 'req_message' => $lang_common['Message']); -$focus_element = array('edit', 'req_message'); -define('PUN_ACTIVE_PAGE', 'index'); -require PUN_ROOT.'header.php'; - -$cur_index = 1; - -?> -
    -
    -
      -
    • -
    • » 
    • -
    • » 
    • -
    • » 
    • -
    -
    -
    - - -
    -

    -
    -
    -

    -
      -'.$cur_error.''."\n"; -?> -
    -
    -
    -
    - - -
    -

    -
    -
    -
    -
    -
    - -
    -
    -
    -
    -
    -
    - - -
    -

    -
    -
    -
    -
    - - -
    - - - -
    -
    -'.$lang_post['Hide smilies'].'
    '; - else - $checkboxes[] = ''; -} - -if ($is_admmod) -{ - if ((isset($_POST['form_sent']) && isset($_POST['silent'])) || !isset($_POST['form_sent'])) - $checkboxes[] = ''; - else - $checkboxes[] = ''; -} - -if (!empty($checkboxes)) -{ - -?> -
    -
    -
    - -
    -
    - -
    -
    -
    - -
    -

    -
    -
    -
    -'s) - - fid: One or more forum IDs (comma-separated). If ignored, - topics from all readable forums will be pulled. - - nfid: One or more forum IDs (comma-separated) that are to be - excluded. E.g. the ID of a a test forum. - - tid: A topic ID from which to show posts. If a tid is supplied, - fid and nfid are ignored. - - show: Any integer value between 1 and 50. The default is 15. - - order: last_post - show topics ordered by when they were last - posted in, giving information about the reply. - posted - show topics ordered by when they were first - posted, giving information about the original post. - ------------------------------------------------------------------------------*/ - -define('PUN_QUIET_VISIT', 1); - -if (!defined('PUN_ROOT')) - define('PUN_ROOT', './'); -require PUN_ROOT.'include/common.php'; - -// The length at which topic subjects will be truncated (for HTML output) -if (!defined('FORUM_EXTERN_MAX_SUBJECT_LENGTH')) - define('FORUM_EXTERN_MAX_SUBJECT_LENGTH', 30); - -// If we're a guest and we've sent a username/pass, we can try to authenticate using those details -if ($pun_user['is_guest'] && isset($_SERVER['PHP_AUTH_USER'])) - authenticate_user($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']); - -if ($pun_user['g_read_board'] == '0') -{ - http_authenticate_user(); - exit($lang_common['No view']); -} - -$action = isset($_GET['action']) ? $_GET['action'] : 'feed'; - - -// -// Sends the proper headers for Basic HTTP Authentication -// -function http_authenticate_user() -{ - global $pun_config, $pun_user; - - if (!$pun_user['is_guest']) - return; - - header('WWW-Authenticate: Basic realm="'.$pun_config['o_board_title'].' External Syndication"'); - header('HTTP/1.0 401 Unauthorized'); -} - - -// -// Output $feed as RSS 2.0 -// -function output_rss($feed) -{ - global $lang_common, $pun_config; - - // Send XML/no cache headers - header('Content-Type: text/xml; charset=utf-8'); - header('Expires: '.gmdate('D, d M Y H:i:s').' GMT'); - header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); - header('Pragma: public'); - - echo ''."\n"; - echo ''."\n"; - echo "\t".''."\n"; - echo "\t\t".'<![CDATA['.escape_cdata($feed['title']).']]>'."\n"; - echo "\t\t".''.$feed['link'].''."\n"; - echo "\t\t".''."\n"; - echo "\t\t".''.gmdate('r', count($feed['items']) ? $feed['items'][0]['pubdate'] : time()).''."\n"; - - if ($pun_config['o_show_version'] == '1') - echo "\t\t".'FluxBB '.$pun_config['o_cur_version'].''."\n"; - else - echo "\t\t".'FluxBB'."\n"; - - foreach ($feed['items'] as $item) - { - echo "\t\t".''."\n"; - echo "\t\t\t".'<![CDATA['.escape_cdata($item['title']).']]>'."\n"; - echo "\t\t\t".''.$item['link'].''."\n"; - echo "\t\t\t".''."\n"; - echo "\t\t\t".''."\n"; - echo "\t\t\t".''.gmdate('r', $item['pubdate']).''."\n"; - echo "\t\t\t".''.$item['link'].''."\n"; - - echo "\t\t".''."\n"; - } - - echo "\t".''."\n"; - echo ''."\n"; -} - - -// -// Output $feed as Atom 1.0 -// -function output_atom($feed) -{ - global $lang_common, $pun_config; - - // Send XML/no cache headers - header('Content-Type: text/xml; charset=utf-8'); - header('Expires: '.gmdate('D, d M Y H:i:s').' GMT'); - header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); - header('Pragma: public'); - - echo ''."\n"; - echo ''."\n"; - - echo "\t".'<![CDATA['.escape_cdata($feed['title']).']]>'."\n"; - echo "\t".''."\n"; - echo "\t".''."\n"; - echo "\t".''.gmdate('Y-m-d\TH:i:s\Z', count($feed['items']) ? $feed['items'][0]['pubdate'] : time()).''."\n"; - - if ($pun_config['o_show_version'] == '1') - echo "\t".'FluxBB'."\n"; - else - echo "\t".'FluxBB'."\n"; - - echo "\t".''.$feed['link'].''."\n"; - - $content_tag = ($feed['type'] == 'posts') ? 'content' : 'summary'; - - foreach ($feed['items'] as $item) - { - echo "\t".''."\n"; - echo "\t\t".'<![CDATA['.escape_cdata($item['title']).']]>'."\n"; - echo "\t\t".''."\n"; - echo "\t\t".'<'.$content_tag.' type="html">'."\n"; - echo "\t\t".''."\n"; - echo "\t\t\t".''."\n"; - - if (isset($item['author']['email'])) - echo "\t\t\t".''."\n"; - - if (isset($item['author']['uri'])) - echo "\t\t\t".''.$item['author']['uri'].''."\n"; - - echo "\t\t".''."\n"; - echo "\t\t".''.gmdate('Y-m-d\TH:i:s\Z', $item['pubdate']).''."\n"; - - echo "\t\t".''.$item['link'].''."\n"; - echo "\t".''."\n"; - } - - echo ''."\n"; -} - - -// -// Output $feed as XML -// -function output_xml($feed) -{ - global $lang_common, $pun_config; - - // Send XML/no cache headers - header('Content-Type: text/xml; charset=utf-8'); - header('Expires: '.gmdate('D, d M Y H:i:s').' GMT'); - header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); - header('Pragma: public'); - - echo ''."\n"; - echo ''."\n"; - echo "\t".''.$feed['link'].''."\n"; - - $forum_tag = ($feed['type'] == 'posts') ? 'post' : 'topic'; - - foreach ($feed['items'] as $item) - { - echo "\t".'<'.$forum_tag.' id="'.$item['id'].'">'."\n"; - - echo "\t\t".'<![CDATA['.escape_cdata($item['title']).']]>'."\n"; - echo "\t\t".''.$item['link'].''."\n"; - echo "\t\t".''."\n"; - echo "\t\t".''."\n"; - echo "\t\t\t".''."\n"; - - if (isset($item['author']['email'])) - echo "\t\t\t".''."\n"; - - if (isset($item['author']['uri'])) - echo "\t\t\t".''.$item['author']['uri'].''."\n"; - - echo "\t\t".''."\n"; - echo "\t\t".''.gmdate('r', $item['pubdate']).''."\n"; - - echo "\t".''."\n"; - } - - echo ''."\n"; -} - - -// -// Output $feed as HTML (using
  • tags) -// -function output_html($feed) -{ - - // Send the Content-type header in case the web server is setup to send something else - header('Content-type: text/html; charset=utf-8'); - header('Expires: '.gmdate('D, d M Y H:i:s').' GMT'); - header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); - header('Pragma: public'); - - foreach ($feed['items'] as $item) - { - if (utf8_strlen($item['title']) > FORUM_EXTERN_MAX_SUBJECT_LENGTH) - $subject_truncated = pun_htmlspecialchars(pun_trim(utf8_substr($item['title'], 0, (FORUM_EXTERN_MAX_SUBJECT_LENGTH - 5)))).' …'; - else - $subject_truncated = pun_htmlspecialchars($item['title']); - - echo '
  • '.$subject_truncated.'
  • '."\n"; - } -} - -// Show recent discussions -if ($action == 'feed') -{ - require PUN_ROOT.'include/parser.php'; - - // Determine what type of feed to output - $type = isset($_GET['type']) && in_array($_GET['type'], array('html', 'rss', 'atom', 'xml')) ? $_GET['type'] : 'html'; - - $show = isset($_GET['show']) ? intval($_GET['show']) : 15; - if ($show < 1 || $show > 50) - $show = 15; - - // Was a topic ID supplied? - if (isset($_GET['tid'])) - { - $tid = intval($_GET['tid']); - - // Fetch topic subject - $result = $db->query('SELECT t.subject, t.first_post_id FROM '.$db->prefix.'topics AS t LEFT JOIN '.$db->prefix.'forum_perms AS fp ON (fp.forum_id=t.forum_id AND fp.group_id='.$pun_user['g_id'].') WHERE (fp.read_forum IS NULL OR fp.read_forum=1) AND t.moved_to IS NULL AND t.id='.$tid) or error('Unable to fetch topic info', __FILE__, __LINE__, $db->error()); - if (!$db->num_rows($result)) - { - http_authenticate_user(); - exit($lang_common['Bad request']); - } - - $cur_topic = $db->fetch_assoc($result); - - if ($pun_config['o_censoring'] == '1') - $cur_topic['subject'] = censor_words($cur_topic['subject']); - - // Setup the feed - $feed = array( - 'title' => $pun_config['o_board_title'].$lang_common['Title separator'].$cur_topic['subject'], - 'link' => $pun_config['o_base_url'].'/viewtopic.php?id='.$tid, - 'description' => sprintf($lang_common['RSS description topic'], $cur_topic['subject']), - 'items' => array(), - 'type' => 'posts' - ); - - // Fetch $show posts - $result = $db->query('SELECT p.id, p.poster, p.message, p.hide_smilies, p.posted, p.poster_id, u.email_setting, u.email, p.poster_email FROM '.$db->prefix.'posts AS p INNER JOIN '.$db->prefix.'users AS u ON u.id=p.poster_id WHERE p.topic_id='.$tid.' ORDER BY p.posted DESC LIMIT '.$show) or error('Unable to fetch post info', __FILE__, __LINE__, $db->error()); - while ($cur_post = $db->fetch_assoc($result)) - { - $cur_post['message'] = parse_message($cur_post['message'], $cur_post['hide_smilies']); - - $item = array( - 'id' => $cur_post['id'], - 'title' => $cur_topic['first_post_id'] == $cur_post['id'] ? $cur_topic['subject'] : $lang_common['RSS reply'].$cur_topic['subject'], - 'link' => $pun_config['o_base_url'].'/viewtopic.php?pid='.$cur_post['id'].'#p'.$cur_post['id'], - 'description' => $cur_post['message'], - 'author' => array( - 'name' => $cur_post['poster'], - ), - 'pubdate' => $cur_post['posted'] - ); - - if ($cur_post['poster_id'] > 1) - { - if ($cur_post['email_setting'] == '0' && !$pun_user['is_guest']) - $item['author']['email'] = $cur_post['email']; - - $item['author']['uri'] = $pun_config['o_base_url'].'/profile.php?id='.$cur_post['poster_id']; - } - else if ($cur_post['poster_email'] != '' && !$pun_user['is_guest']) - $item['author']['email'] = $cur_post['poster_email']; - - $feed['items'][] = $item; - } - - $output_func = 'output_'.$type; - $output_func($feed); - } - else - { - $order_posted = isset($_GET['order']) && $_GET['order'] == 'posted'; - $forum_name = ''; - $forum_sql = ''; - - // Were any forum IDs supplied? - if (isset($_GET['fid']) && is_scalar($_GET['fid']) && $_GET['fid'] != '') - { - $fids = explode(',', pun_trim($_GET['fid'])); - $fids = array_map('intval', $fids); - - if (!empty($fids)) - $forum_sql = ' AND t.forum_id IN('.implode(',', $fids).')'; - - if (count($fids) == 1) - { - // Fetch forum name - $result = $db->query('SELECT f.forum_name FROM '.$db->prefix.'forums AS f LEFT JOIN '.$db->prefix.'forum_perms AS fp ON (fp.forum_id=f.id AND fp.group_id='.$pun_user['g_id'].') WHERE (fp.read_forum IS NULL OR fp.read_forum=1) AND f.id='.$fids[0]) or error('Unable to fetch forum name', __FILE__, __LINE__, $db->error()); - if ($db->num_rows($result)) - $forum_name = $lang_common['Title separator'].$db->result($result); - } - } - - // Any forum IDs to exclude? - if (isset($_GET['nfid']) && is_scalar($_GET['nfid']) && $_GET['nfid'] != '') - { - $nfids = explode(',', pun_trim($_GET['nfid'])); - $nfids = array_map('intval', $nfids); - - if (!empty($nfids)) - $forum_sql = ' AND t.forum_id NOT IN('.implode(',', $nfids).')'; - } - - // Setup the feed - $feed = array( - 'title' => $pun_config['o_board_title'].$forum_name, - 'link' => $pun_config['o_base_url'].'/index.php', - 'description' => sprintf($lang_common['RSS description'], $pun_config['o_board_title']), - 'items' => array(), - 'type' => 'topics' - ); - - // Fetch $show topics - $result = $db->query('SELECT t.id, t.poster, t.subject, t.posted, t.last_post, t.last_poster, p.message, p.hide_smilies, u.email_setting, u.email, p.poster_id, p.poster_email FROM '.$db->prefix.'topics AS t INNER JOIN '.$db->prefix.'posts AS p ON p.id='.($order_posted ? 't.first_post_id' : 't.last_post_id').' INNER JOIN '.$db->prefix.'users AS u ON u.id=p.poster_id LEFT JOIN '.$db->prefix.'forum_perms AS fp ON (fp.forum_id=t.forum_id AND fp.group_id='.$pun_user['g_id'].') WHERE (fp.read_forum IS NULL OR fp.read_forum=1) AND t.moved_to IS NULL'.$forum_sql.' ORDER BY '.($order_posted ? 't.posted' : 't.last_post').' DESC LIMIT '.$show) or error('Unable to fetch topic info', __FILE__, __LINE__, $db->error()); - while ($cur_topic = $db->fetch_assoc($result)) - { - if ($pun_config['o_censoring'] == '1') - $cur_topic['subject'] = censor_words($cur_topic['subject']); - - $cur_topic['message'] = parse_message($cur_topic['message'], $cur_topic['hide_smilies']); - - $item = array( - 'id' => $cur_topic['id'], - 'title' => $cur_topic['subject'], - 'link' => $pun_config['o_base_url'].($order_posted ? '/viewtopic.php?id='.$cur_topic['id'] : '/viewtopic.php?id='.$cur_topic['id'].'&action=new'), - 'description' => $cur_topic['message'], - 'author' => array( - 'name' => $order_posted ? $cur_topic['poster'] : $cur_topic['last_poster'] - ), - 'pubdate' => $order_posted ? $cur_topic['posted'] : $cur_topic['last_post'] - ); - - if ($cur_topic['poster_id'] > 1) - { - if ($cur_topic['email_setting'] == '0' && !$pun_user['is_guest']) - $item['author']['email'] = $cur_topic['email']; - - $item['author']['uri'] = $pun_config['o_base_url'].'/profile.php?id='.$cur_topic['poster_id']; - } - else if ($cur_topic['poster_email'] != '' && !$pun_user['is_guest']) - $item['author']['email'] = $cur_topic['poster_email']; - - $feed['items'][] = $item; - } - - $output_func = 'output_'.$type; - $output_func($feed); - } - - exit; -} - -// Show users online -else if ($action == 'online' || $action == 'online_full') -{ - // Load the index.php language file - require PUN_ROOT.'lang/'.$pun_config['o_default_lang'].'/index.php'; - - // Fetch users online info and generate strings for output - $num_guests = $num_users = 0; - $users = array(); - - $result = $db->query('SELECT user_id, ident FROM '.$db->prefix.'online WHERE idle=0 ORDER BY ident', true) or error('Unable to fetch online list', __FILE__, __LINE__, $db->error()); - - while ($pun_user_online = $db->fetch_assoc($result)) - { - if ($pun_user_online['user_id'] > 1) - { - $users[] = ($pun_user['g_view_users'] == '1') ? ''.pun_htmlspecialchars($pun_user_online['ident']).'' : pun_htmlspecialchars($pun_user_online['ident']); - ++$num_users; - } - else - ++$num_guests; - } - - // Send the Content-type header in case the web server is setup to send something else - header('Content-type: text/html; charset=utf-8'); - header('Expires: '.gmdate('D, d M Y H:i:s').' GMT'); - header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); - header('Pragma: public'); - - echo $lang_index['Guests online'].': '.forum_number_format($num_guests).'
    '."\n"; - - if ($action == 'online_full' && !empty($users)) - echo $lang_index['Users online'].': '.implode(', ', $users).'
    '."\n"; - else - echo $lang_index['Users online'].': '.forum_number_format($num_users).'
    '."\n"; - - exit; -} - -// Show board statistics -else if ($action == 'stats') -{ - // Load the index.php language file - require PUN_ROOT.'lang/'.$pun_config['o_default_lang'].'/index.php'; - - // Collect some statistics from the database - $result = $db->query('SELECT COUNT(id)-1 FROM '.$db->prefix.'users WHERE group_id!='.PUN_UNVERIFIED) or error('Unable to fetch total user count', __FILE__, __LINE__, $db->error()); - $stats['total_users'] = $db->result($result); - - $result = $db->query('SELECT id, username FROM '.$db->prefix.'users WHERE group_id!='.PUN_UNVERIFIED.' ORDER BY registered DESC LIMIT 1') or error('Unable to fetch newest registered user', __FILE__, __LINE__, $db->error()); - $stats['last_user'] = $db->fetch_assoc($result); - - $result = $db->query('SELECT SUM(num_topics), SUM(num_posts) FROM '.$db->prefix.'forums') or error('Unable to fetch topic/post count', __FILE__, __LINE__, $db->error()); - list($stats['total_topics'], $stats['total_posts']) = $db->fetch_row($result); - - // Send the Content-type header in case the web server is setup to send something else - header('Content-type: text/html; charset=utf-8'); - header('Expires: '.gmdate('D, d M Y H:i:s').' GMT'); - header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); - header('Pragma: public'); - - echo $lang_index['No of users'].': '.forum_number_format($stats['total_users']).'
    '."\n"; - echo $lang_index['Newest user'].': '.(($pun_user['g_view_users'] == '1') ? ''.pun_htmlspecialchars($stats['last_user']['username']).'' : pun_htmlspecialchars($stats['last_user']['username'])).'
    '."\n"; - echo $lang_index['No of topics'].': '.forum_number_format($stats['total_topics']).'
    '."\n"; - echo $lang_index['No of posts'].': '.forum_number_format($stats['total_posts']).'
    '."\n"; - - exit; -} - -// If we end up here, the script was called with some wacky parameters -exit($lang_common['Bad request']); diff --git a/upload/footer.php b/upload/footer.php deleted file mode 100644 index 4575702..0000000 --- a/upload/footer.php +++ /dev/null @@ -1,173 +0,0 @@ -', $tpl_temp, $tpl_main); -ob_end_clean(); -// END SUBST - - - -// START SUBST - -ob_start(); - -?> -
    -

    -
    -
    -'."\n"; - - if (!$pun_user['is_guest'] && $pun_user['g_search'] == '1') - { - echo "\t\t\t\t".''."\n"; - } - else - { - if ($pun_user['g_search'] == '1') - { - echo "\t\t\t\t".''."\n"; - } - } - - if ($footer_style == 'index') - { - if ($pun_config['o_feed_type'] == '1') - echo "\t\t\t\t".''."\n"; - else if ($pun_config['o_feed_type'] == '2') - echo "\t\t\t\t".''."\n"; - } - - echo "\t\t\t".'
    '."\n"; -} -else if ($footer_style == 'viewforum' || $footer_style == 'viewtopic') -{ - echo "\t\t\t".'
    '."\n"; - - // Display the "Jump to" drop list - if ($pun_config['o_quickjump'] == '1') - { - // Load cached quick jump - if (file_exists(FORUM_CACHE_DIR.'cache_quickjump_'.$pun_user['g_id'].'.php')) - include FORUM_CACHE_DIR.'cache_quickjump_'.$pun_user['g_id'].'.php'; - - if (!defined('PUN_QJ_LOADED')) - { - if (!defined('FORUM_CACHE_FUNCTIONS_LOADED')) - require PUN_ROOT.'include/cache.php'; - - generate_quickjump_cache($pun_user['g_id']); - require FORUM_CACHE_DIR.'cache_quickjump_'.$pun_user['g_id'].'.php'; - } - } - - if ($footer_style == 'viewforum') - { - if ($is_admmod) - echo "\t\t\t\t".'

    '.$lang_common['Moderate forum'].'

    '."\n"; - - if ($pun_config['o_feed_type'] == '1') - echo "\t\t\t\t".''."\n"; - else if ($pun_config['o_feed_type'] == '2') - echo "\t\t\t\t".''."\n"; - } - else if ($footer_style == 'viewtopic') - { - if ($is_admmod) - { - echo "\t\t\t\t".'
    '."\n"; - echo "\t\t\t\t\t".'
    '.$lang_topic['Mod controls'].'
    '."\n"; - - echo "\t\t\t\t\t".'
    '.$lang_common['Moderate topic'].'
    '."\n"; - echo "\t\t\t\t\t".'
    '.$lang_common['Move topic'].'
    '."\n"; - - if ($cur_topic['closed'] == '1') - echo "\t\t\t\t\t".'
    '.$lang_common['Open topic'].'
    '."\n"; - else - echo "\t\t\t\t\t".'
    '.$lang_common['Close topic'].'
    '."\n"; - - if ($cur_topic['sticky'] == '1') - echo "\t\t\t\t\t".'
    '.$lang_common['Unstick topic'].'
    '."\n"; - else - echo "\t\t\t\t\t".'
    '.$lang_common['Stick topic'].'
    '."\n"; - - echo "\t\t\t\t".'
    '."\n"; - } - - if ($pun_config['o_feed_type'] == '1') - echo "\t\t\t\t".''."\n"; - else if ($pun_config['o_feed_type'] == '2') - echo "\t\t\t\t".''."\n"; - } - - echo "\t\t\t".'
    '."\n"; -} - -?> -

    FluxBB'.(($pun_config['o_show_version'] == '1') ? ' '.$pun_config['o_cur_version'] : '')) ?>

    -
    -
    -
    - -[ '.sprintf($lang_common['Querytime'], $time_diff, $db->get_num_queries()).' - Memory usage: '. - file_size(memory_get_usage()).', Peak: '.file_size(memory_get_peak_usage()).' ]

    '."\n"; -} - - -// End the transaction -$db->end_transaction(); - -// Display executed queries (if enabled) -if (defined('PUN_SHOW_QUERIES')) - display_saved_queries(); - -$tpl_temp = trim(ob_get_contents()); -$tpl_main = str_replace('', $tpl_temp, $tpl_main); -ob_end_clean(); -// END SUBST - - - -// Close the db connection (and free up any result data) -$db->close(); - -// Spit out the page -exit($tpl_main); diff --git a/upload/header.php b/upload/header.php deleted file mode 100644 index 258b588..0000000 --- a/upload/header.php +++ /dev/null @@ -1,241 +0,0 @@ - -preg_match_all('##', $tpl_main, $pun_includes, PREG_SET_ORDER); - -foreach ($pun_includes as $cur_include) -{ - if (!file_exists($tpl_inc_dir.$cur_include[1].'.'.$cur_include[2])) - error(sprintf($lang_common['Pun include error'], htmlspecialchars($cur_include[0]), basename($tpl_file), $tpl_inc_dir)); - - ob_start(); - - require $tpl_inc_dir.$cur_include[1].'.'.$cur_include[2]; - - $tpl_temp = ob_get_contents(); - $tpl_main = str_replace($cur_include[0], $tpl_temp, $tpl_main); - ob_end_clean(); -} -// END SUBST - - - -// START SUBST - -$tpl_main = str_replace('', $lang_common['lang_identifier'], $tpl_main); -// END SUBST - - - -// START SUBST - -$tpl_main = str_replace('', $lang_common['lang_direction'], $tpl_main); -// END SUBST - - - -// START SUBST - -ob_start(); - -// Define $p if its not set to avoid a PHP notice -$p = isset($p) ? $p : null; - -// Is this a page that we want search index spiders to index? -if (!defined('PUN_ALLOW_INDEX')) - echo ''."\n"; - -?> -<?php echo generate_page_title($page_title, $p) ?> - -'."\n"; - else - echo ''."\n"; -} - -if (isset($required_fields)) -{ - // Output JavaScript to validate form (make sure required fields are filled out) - -?> - -'."\n"; - -if (isset($page_head)) - echo implode("\n", $page_head)."\n"; - -$tpl_temp = trim(ob_get_contents()); -$tpl_main = str_replace('', $tpl_temp, $tpl_main); -ob_end_clean(); -// END SUBST - - - -// START SUBST - -if (isset($focus_element)) -{ - $tpl_main = str_replace('', '', $tpl_main); -} -// END SUBST - - - -// START SUBST - -$tpl_main = str_replace('', htmlspecialchars(basename($_SERVER['PHP_SELF'], '.php')), $tpl_main); -// END SUBST - - - -// START SUBST - -$tpl_main = str_replace('', '

    '.pun_htmlspecialchars($pun_config['o_board_title']).'

    ', $tpl_main); -// END SUBST - - - -// START SUBST - -$tpl_main = str_replace('', '
    '.$pun_config['o_board_desc'].'
    ', $tpl_main); -// END SUBST - - - -// START SUBST - -$tpl_main = str_replace('','
    '."\n\t\t\t". generate_navlinks()."\n\t\t".'
    ', $tpl_main); -// END SUBST - - - -// START SUBST - -if ($pun_user['is_guest']) - $tpl_temp = '
    '."\n\t\t\t".'

    '.$lang_common['Not logged in'].'

    '."\n\t\t".'
    '; -else -{ - $tpl_temp = '
    '."\n\t\t\t".'
      '."\n\t\t\t\t".'
    • '.$lang_common['Logged in as'].' '.pun_htmlspecialchars($pun_user['username']).'
    • '."\n\t\t\t\t".'
    • '.sprintf($lang_common['Last visit'], format_time($pun_user['last_visit'])).'
    • '; - - if ($pun_user['is_admmod']) - { - if ($pun_config['o_report_method'] == '0' || $pun_config['o_report_method'] == '2') - { - $result_header = $db->query('SELECT 1 FROM '.$db->prefix.'reports WHERE zapped IS NULL') or error('Unable to fetch reports info', __FILE__, __LINE__, $db->error()); - - if ($db->result($result_header)) - $tpl_temp .= "\n\t\t\t\t".''; - } - - if ($pun_config['o_maintenance'] == '1') - $tpl_temp .= "\n\t\t\t\t".''; - } - - if (in_array(basename($_SERVER['PHP_SELF']), array('index.php', 'search.php'))) - $tpl_temp .= "\n\t\t\t".'
    '."\n\t\t\t".''."\n\t\t\t".'
    '."\n\t\t".'
    '; - else if (basename($_SERVER['PHP_SELF']) == 'viewforum.php') - $tpl_temp .= "\n\t\t\t".''."\n\t\t\t".''."\n\t\t\t".'
    '."\n\t\t".''; - else - $tpl_temp .= "\n\t\t\t".''."\n\t\t\t".'
    '."\n\t\t".''; -} - -$tpl_main = str_replace('', $tpl_temp, $tpl_main); -// END SUBST - - - -// START SUBST - -if ($pun_config['o_announcement'] == '1') -{ - ob_start(); - -?> -
    -

    -
    -
    -
    -
    -
    -
    -', $tpl_temp, $tpl_main); - ob_end_clean(); -} -else - $tpl_main = str_replace('', '', $tpl_main); -// END SUBST - - - -// START SUBST - -ob_start(); - - -define('PUN_HEADER', 1); diff --git a/upload/help.php b/upload/help.php deleted file mode 100644 index 765e20f..0000000 --- a/upload/help.php +++ /dev/null @@ -1,140 +0,0 @@ - -

    -
    -
    -

    -

    -
    -
    -

    -
    -
    -

    -

    [b][/b]

    -

    [u][/u]

    -

    [i][/i]

    -

    [color=#FF0000][/color]

    -

    [color=blue][/color]

    -

    [h][/h]

    -
    -
    -

    -
    -
    -

    -

    [url=][/url]

    -

    [url][/url]

    -

    [email]myname@mydomain.com[/email] myname@mydomain.com

    -

    [email=myname@mydomain.com][/email]

    -
    -
    -

    -

    [img=FluxBB bbcode test]img/test.png[/img] FluxBB bbcode test

    -
    -
    -

    -
    -
    -

    -

    [quote=James][/quote]

    -

    -
    -
    James

    -
    -

    -

    [quote][/quote]

    -

    -
    -

    -
    -

    -
    -
    -

    -
    -
    -

    -

    [code][/code]

    -

    -
    -
    -
    -
    -
    -

    -
    -
    -

    -

    [list][*][/*][*][/*][*][/*][/list]

    -
    -
    -
    -

    [list=1][*][/*][*][/*][*][/*][/list]

    -
    -
    -
    -

    [list=a][*][/*][*][/*][*][/*][/list]

    -
    -
    -
    -
    -
    -

    -
    -
    -

    -

    [b][u][/u][/b]

    -
    -
    -

    -
    -
    -

    -
    - $smiley_img) - $smiley_groups[$smiley_img][] = $smiley_text; - -foreach ($smiley_groups as $smiley_img => $smiley_texts) - echo "\t\t\t".'

    '.implode(' '.$lang_common['and'].' ', $smiley_texts).' '.$lang_help['produces'].' '.$smiley_texts[0].'

    '."\n"; - -?> -
    -
    -
    -.. diff --git a/upload/img/index.html b/upload/img/index.html deleted file mode 100644 index 89337b2..0000000 --- a/upload/img/index.html +++ /dev/null @@ -1 +0,0 @@ -.. diff --git a/upload/img/smilies/big_smile.png b/upload/img/smilies/big_smile.png deleted file mode 100644 index b29719b..0000000 Binary files a/upload/img/smilies/big_smile.png and /dev/null differ diff --git a/upload/img/smilies/cool.png b/upload/img/smilies/cool.png deleted file mode 100644 index a875361..0000000 Binary files a/upload/img/smilies/cool.png and /dev/null differ diff --git a/upload/img/smilies/hmm.png b/upload/img/smilies/hmm.png deleted file mode 100644 index 69e416a..0000000 Binary files a/upload/img/smilies/hmm.png and /dev/null differ diff --git a/upload/img/smilies/index.html b/upload/img/smilies/index.html deleted file mode 100644 index 89337b2..0000000 --- a/upload/img/smilies/index.html +++ /dev/null @@ -1 +0,0 @@ -.. diff --git a/upload/img/smilies/lol.png b/upload/img/smilies/lol.png deleted file mode 100644 index dd9058b..0000000 Binary files a/upload/img/smilies/lol.png and /dev/null differ diff --git a/upload/img/smilies/mad.png b/upload/img/smilies/mad.png deleted file mode 100644 index 011079d..0000000 Binary files a/upload/img/smilies/mad.png and /dev/null differ diff --git a/upload/img/smilies/neutral.png b/upload/img/smilies/neutral.png deleted file mode 100644 index 9bc5ca0..0000000 Binary files a/upload/img/smilies/neutral.png and /dev/null differ diff --git a/upload/img/smilies/roll.png b/upload/img/smilies/roll.png deleted file mode 100644 index e2e8e2a..0000000 Binary files a/upload/img/smilies/roll.png and /dev/null differ diff --git a/upload/img/smilies/sad.png b/upload/img/smilies/sad.png deleted file mode 100644 index c14e144..0000000 Binary files a/upload/img/smilies/sad.png and /dev/null differ diff --git a/upload/img/smilies/smile.png b/upload/img/smilies/smile.png deleted file mode 100644 index 44cc239..0000000 Binary files a/upload/img/smilies/smile.png and /dev/null differ diff --git a/upload/img/smilies/tongue.png b/upload/img/smilies/tongue.png deleted file mode 100644 index 5302c89..0000000 Binary files a/upload/img/smilies/tongue.png and /dev/null differ diff --git a/upload/img/smilies/wink.png b/upload/img/smilies/wink.png deleted file mode 100644 index 595c1fe..0000000 Binary files a/upload/img/smilies/wink.png and /dev/null differ diff --git a/upload/img/smilies/yikes.png b/upload/img/smilies/yikes.png deleted file mode 100644 index bb4aefd..0000000 Binary files a/upload/img/smilies/yikes.png and /dev/null differ diff --git a/upload/img/test.png b/upload/img/test.png deleted file mode 100644 index 571ad8e..0000000 Binary files a/upload/img/test.png and /dev/null differ diff --git a/upload/include/cache.php b/upload/include/cache.php deleted file mode 100644 index fba95e3..0000000 --- a/upload/include/cache.php +++ /dev/null @@ -1,145 +0,0 @@ -query('SELECT * FROM '.$db->prefix.'config', true) or error('Unable to fetch forum config', __FILE__, __LINE__, $db->error()); - while ($cur_config_item = $db->fetch_row($result)) - $output[$cur_config_item[0]] = $cur_config_item[1]; - - // Output config as PHP code - $fh = @fopen(FORUM_CACHE_DIR.'cache_config.php', 'wb'); - if (!$fh) - error('Unable to write configuration cache file to cache directory. Please make sure PHP has write access to the directory \'cache\'', __FILE__, __LINE__); - - fwrite($fh, ''); - - fclose($fh); -} - - -// -// Generate the bans cache PHP script -// -function generate_bans_cache() -{ - global $db; - - // Get the ban list from the DB - $result = $db->query('SELECT * FROM '.$db->prefix.'bans', true) or error('Unable to fetch ban list', __FILE__, __LINE__, $db->error()); - - $output = array(); - while ($cur_ban = $db->fetch_assoc($result)) - $output[] = $cur_ban; - - // Output ban list as PHP code - $fh = @fopen(FORUM_CACHE_DIR.'cache_bans.php', 'wb'); - if (!$fh) - error('Unable to write bans cache file to cache directory. Please make sure PHP has write access to the directory \'cache\'', __FILE__, __LINE__); - - fwrite($fh, ''); - - fclose($fh); -} - - -// -// Generate the ranks cache PHP script -// -function generate_ranks_cache() -{ - global $db; - - // Get the rank list from the DB - $result = $db->query('SELECT * FROM '.$db->prefix.'ranks ORDER BY min_posts', true) or error('Unable to fetch rank list', __FILE__, __LINE__, $db->error()); - - $output = array(); - while ($cur_rank = $db->fetch_assoc($result)) - $output[] = $cur_rank; - - // Output ranks list as PHP code - $fh = @fopen(FORUM_CACHE_DIR.'cache_ranks.php', 'wb'); - if (!$fh) - error('Unable to write ranks cache file to cache directory. Please make sure PHP has write access to the directory \'cache\'', __FILE__, __LINE__); - - fwrite($fh, ''); - - fclose($fh); -} - - -// -// Generate quick jump cache PHP scripts -// -function generate_quickjump_cache($group_id = false) -{ - global $db, $lang_common, $pun_user; - - // If a group_id was supplied, we generate the quick jump cache for that group only - if ($group_id !== false) - $groups[0] = $group_id; - else - { - // A group_id was now supplied, so we generate the quick jump cache for all groups - $result = $db->query('SELECT g_id FROM '.$db->prefix.'groups') or error('Unable to fetch user group list', __FILE__, __LINE__, $db->error()); - $num_groups = $db->num_rows($result); - - for ($i = 0; $i < $num_groups; ++$i) - $groups[] = $db->result($result, $i); - } - - // Loop through the groups in $groups and output the cache for each of them - while (list(, $group_id) = @each($groups)) - { - // Output quick jump as PHP code - $fh = @fopen(FORUM_CACHE_DIR.'cache_quickjump_'.$group_id.'.php', 'wb'); - if (!$fh) - error('Unable to write quick jump cache file to cache directory. Please make sure PHP has write access to the directory \'cache\'', __FILE__, __LINE__); - - $output = ''; - $output .= "\t\t\t\t".'
    '."\n\t\t\t\t\t".'
    '."\n\t\t\t\t".'
    '."\n"; - - fwrite($fh, $output); - - fclose($fh); - } -} - -define('FORUM_CACHE_FUNCTIONS_LOADED', true); diff --git a/upload/include/common.php b/upload/include/common.php deleted file mode 100644 index 46d990f..0000000 --- a/upload/include/common.php +++ /dev/null @@ -1,176 +0,0 @@ -install.php to install FluxBB first.'); - -// Load the functions script -require PUN_ROOT.'include/functions.php'; - -// Load UTF-8 functions -require PUN_ROOT.'include/utf8/utf8.php'; - -// Strip out "bad" UTF-8 characters -forum_remove_bad_characters(); - -// Reverse the effect of register_globals -forum_unregister_globals(); - -// Record the start time (will be used to calculate the generation time for the page) -$pun_start = get_microtime(); - -// Make sure PHP reports all errors except E_NOTICE. FluxBB supports E_ALL, but a lot of scripts it may interact with, do not -error_reporting(E_ALL ^ E_NOTICE); - -// Force POSIX locale (to prevent functions such as strtolower() from messing up UTF-8 strings) -setlocale(LC_CTYPE, 'C'); - -// Turn off magic_quotes_runtime -if (get_magic_quotes_runtime()) - set_magic_quotes_runtime(0); - -// Strip slashes from GET/POST/COOKIE (if magic_quotes_gpc is enabled) -if (get_magic_quotes_gpc()) -{ - function stripslashes_array($array) - { - return is_array($array) ? array_map('stripslashes_array', $array) : stripslashes($array); - } - - $_GET = stripslashes_array($_GET); - $_POST = stripslashes_array($_POST); - $_COOKIE = stripslashes_array($_COOKIE); - $_REQUEST = stripslashes_array($_REQUEST); -} - -// If a cookie name is not specified in config.php, we use the default (pun_cookie) -if (empty($cookie_name)) - $cookie_name = 'pun_cookie'; - -// If the cache directory is not specified, we use the default setting -if (!defined('FORUM_CACHE_DIR')) - define('FORUM_CACHE_DIR', PUN_ROOT.'cache/'); - -// Define a few commonly used constants -define('PUN_UNVERIFIED', 0); -define('PUN_ADMIN', 1); -define('PUN_MOD', 2); -define('PUN_GUEST', 3); -define('PUN_MEMBER', 4); - -// Load DB abstraction layer and connect -require PUN_ROOT.'include/dblayer/common_db.php'; - -// Start a transaction -$db->start_transaction(); - -// Load cached config -if (file_exists(FORUM_CACHE_DIR.'cache_config.php')) - include FORUM_CACHE_DIR.'cache_config.php'; - -if (!defined('PUN_CONFIG_LOADED')) -{ - if (!defined('FORUM_CACHE_FUNCTIONS_LOADED')) - require PUN_ROOT.'include/cache.php'; - - generate_config_cache(); - require FORUM_CACHE_DIR.'cache_config.php'; -} - -// Verify that we are running the proper database schema revision -if (!isset($pun_config['o_database_revision']) || $pun_config['o_database_revision'] < FORUM_DB_REVISION || version_compare($pun_config['o_cur_version'], FORUM_VERSION, '<')) - exit('Your FluxBB database is out-of-date and must be upgraded in order to continue. Please run db_update.php in order to complete the upgrade process.'); - -// Enable output buffering -if (!defined('PUN_DISABLE_BUFFERING')) -{ - // Should we use gzip output compression? - if ($pun_config['o_gzip'] && extension_loaded('zlib')) - ob_start('ob_gzhandler'); - else - ob_start(); -} - -// Define standard date/time formats -$forum_time_formats = array($pun_config['o_time_format'], 'H:i:s', 'H:i', 'g:i:s a', 'g:i a'); -$forum_date_formats = array($pun_config['o_date_format'], 'Y-m-d', 'Y-d-m', 'd-m-Y', 'm-d-Y', 'M j Y', 'jS M Y'); - -// Check/update/set cookie and fetch user info -$pun_user = array(); -check_cookie($pun_user); - -// Attempt to load the common language file -if (file_exists(PUN_ROOT.'lang/'.$pun_user['language'].'/common.php')) - include PUN_ROOT.'lang/'.$pun_user['language'].'/common.php'; -else - error('There is no valid language pack \''.pun_htmlspecialchars($pun_user['language']).'\' installed. Please reinstall a language of that name'); - -// Check if we are to display a maintenance message -if ($pun_config['o_maintenance'] && $pun_user['g_id'] > PUN_ADMIN && !defined('PUN_TURN_OFF_MAINT')) - maintenance_message(); - -// Load cached bans -if (file_exists(FORUM_CACHE_DIR.'cache_bans.php')) - include FORUM_CACHE_DIR.'cache_bans.php'; - -if (!defined('PUN_BANS_LOADED')) -{ - if (!defined('FORUM_CACHE_FUNCTIONS_LOADED')) - require PUN_ROOT.'include/cache.php'; - - generate_bans_cache(); - require FORUM_CACHE_DIR.'cache_bans.php'; -} - -// Check if current user is banned -check_bans(); - -// Update online list -update_users_online(); - -// Check to see if we logged in without a cookie being set -if ($pun_user['is_guest'] && isset($_GET['login'])) - message($lang_common['No cookie']); - -if (!defined('PUN_MAX_POSTSIZE')) - define('PUN_MAX_POSTSIZE', 65535); - -if (!defined('PUN_SEARCH_MIN_WORD')) - define('PUN_SEARCH_MIN_WORD', 3); -if (!defined('PUN_SEARCH_MAX_WORD')) - define('PUN_SEARCH_MAX_WORD', 20); diff --git a/upload/include/common_admin.php b/upload/include/common_admin.php deleted file mode 100644 index 023b7f3..0000000 --- a/upload/include/common_admin.php +++ /dev/null @@ -1,143 +0,0 @@ - -
    -
    -

    -
    -
    -
      - > - > - > - > - > - > - > - > - > - > - > - > - > -
    -
    -
    -read()) !== false) - { - $prefix = substr($entry, 0, strpos($entry, '_')); - $suffix = substr($entry, strlen($entry) - 4); - - if ($suffix == '.php' && ((!$is_admin && $prefix == 'AMP') || ($is_admin && ($prefix == 'AP' || $prefix == 'AMP')))) - $plugins[] = array(substr($entry, strpos($entry, '_') + 1, -4), $entry); - } - $d->close(); - - // Did we find any plugins? - if (!empty($plugins)) - { - -?> -

    - - -
    - -query('SELECT id FROM '.$db->prefix.'topics WHERE forum_id='.$forum_id.$extra_sql, true) or error('Unable to fetch topics', __FILE__, __LINE__, $db->error()); - - $topic_ids = ''; - while ($row = $db->fetch_row($result)) - $topic_ids .= (($topic_ids != '') ? ',' : '').$row[0]; - - if ($topic_ids != '') - { - // Fetch posts to prune - $result = $db->query('SELECT id FROM '.$db->prefix.'posts WHERE topic_id IN('.$topic_ids.')', true) or error('Unable to fetch posts', __FILE__, __LINE__, $db->error()); - - $post_ids = ''; - while ($row = $db->fetch_row($result)) - $post_ids .= (($post_ids != '') ? ',' : '').$row[0]; - - if ($post_ids != '') - { - // Delete topics - $db->query('DELETE FROM '.$db->prefix.'topics WHERE id IN('.$topic_ids.')') or error('Unable to prune topics', __FILE__, __LINE__, $db->error()); - // Delete subscriptions - $db->query('DELETE FROM '.$db->prefix.'subscriptions WHERE topic_id IN('.$topic_ids.')') or error('Unable to prune subscriptions', __FILE__, __LINE__, $db->error()); - // Delete posts - $db->query('DELETE FROM '.$db->prefix.'posts WHERE id IN('.$post_ids.')') or error('Unable to prune posts', __FILE__, __LINE__, $db->error()); - - // We removed a bunch of posts, so now we have to update the search index - require_once PUN_ROOT.'include/search_idx.php'; - strip_search_index($post_ids); - } - } -} diff --git a/upload/include/dblayer/common_db.php b/upload/include/dblayer/common_db.php deleted file mode 100644 index 121d895..0000000 --- a/upload/include/dblayer/common_db.php +++ /dev/null @@ -1,48 +0,0 @@ -.. diff --git a/upload/include/dblayer/mysql.php b/upload/include/dblayer/mysql.php deleted file mode 100644 index c595da4..0000000 --- a/upload/include/dblayer/mysql.php +++ /dev/null @@ -1,347 +0,0 @@ - 'INT(10) UNSIGNED AUTO_INCREMENT' - ); - - - function DBLayer($db_host, $db_username, $db_password, $db_name, $db_prefix, $p_connect) - { - $this->prefix = $db_prefix; - - if ($p_connect) - $this->link_id = @mysql_pconnect($db_host, $db_username, $db_password); - else - $this->link_id = @mysql_connect($db_host, $db_username, $db_password); - - if ($this->link_id) - { - if (!@mysql_select_db($db_name, $this->link_id)) - error('Unable to select database. MySQL reported: '.mysql_error(), __FILE__, __LINE__); - } - else - error('Unable to connect to MySQL server. MySQL reported: '.mysql_error(), __FILE__, __LINE__); - - // Setup the client-server character set (UTF-8) - if (!defined('FORUM_NO_SET_NAMES')) - $this->set_names('utf8'); - - return $this->link_id; - } - - - function start_transaction() - { - return; - } - - - function end_transaction() - { - return; - } - - - function query($sql, $unbuffered = false) - { - if (defined('PUN_SHOW_QUERIES')) - $q_start = get_microtime(); - - if ($unbuffered) - $this->query_result = @mysql_unbuffered_query($sql, $this->link_id); - else - $this->query_result = @mysql_query($sql, $this->link_id); - - if ($this->query_result) - { - if (defined('PUN_SHOW_QUERIES')) - $this->saved_queries[] = array($sql, sprintf('%.5f', get_microtime() - $q_start)); - - ++$this->num_queries; - - return $this->query_result; - } - else - { - if (defined('PUN_SHOW_QUERIES')) - $this->saved_queries[] = array($sql, 0); - - return false; - } - } - - - function result($query_id = 0, $row = 0, $col = 0) - { - return ($query_id) ? @mysql_result($query_id, $row, $col) : false; - } - - - function fetch_assoc($query_id = 0) - { - return ($query_id) ? @mysql_fetch_assoc($query_id) : false; - } - - - function fetch_row($query_id = 0) - { - return ($query_id) ? @mysql_fetch_row($query_id) : false; - } - - - function num_rows($query_id = 0) - { - return ($query_id) ? @mysql_num_rows($query_id) : false; - } - - - function affected_rows() - { - return ($this->link_id) ? @mysql_affected_rows($this->link_id) : false; - } - - - function insert_id() - { - return ($this->link_id) ? @mysql_insert_id($this->link_id) : false; - } - - - function get_num_queries() - { - return $this->num_queries; - } - - - function get_saved_queries() - { - return $this->saved_queries; - } - - - function free_result($query_id = false) - { - return ($query_id) ? @mysql_free_result($query_id) : false; - } - - - function escape($str) - { - if (is_array($str)) - return ''; - else if (function_exists('mysql_real_escape_string')) - return mysql_real_escape_string($str, $this->link_id); - else - return mysql_escape_string($str); - } - - - function error() - { - $result['error_sql'] = @current(@end($this->saved_queries)); - $result['error_no'] = @mysql_errno($this->link_id); - $result['error_msg'] = @mysql_error($this->link_id); - - return $result; - } - - - function close() - { - if ($this->link_id) - { - if ($this->query_result) - @mysql_free_result($this->query_result); - - return @mysql_close($this->link_id); - } - else - return false; - } - - function set_names($names) - { - return $this->query('SET NAMES \''.$this->escape($names).'\''); - } - - function get_version() - { - $result = $this->query('SELECT VERSION()'); - - return array( - 'name' => 'MySQL Standard', - 'version' => preg_replace('/^([^-]+).*$/', '\\1', $this->result($result)) - ); - } - - function table_exists($table_name, $no_prefix = false) - { - $result = $this->query('SHOW TABLES LIKE \''.($no_prefix ? '' : $this->prefix).$this->escape($table_name).'\''); - return $this->num_rows($result) > 0; - } - - - function field_exists($table_name, $field_name, $no_prefix = false) - { - $result = $this->query('SHOW COLUMNS FROM '.($no_prefix ? '' : $this->prefix).$table_name.' LIKE \''.$this->escape($field_name).'\''); - return $this->num_rows($result) > 0; - } - - - function index_exists($table_name, $index_name, $no_prefix = false) - { - $exists = false; - - $result = $this->query('SHOW INDEX FROM '.($no_prefix ? '' : $this->prefix).$table_name); - while ($cur_index = $this->fetch_assoc($result)) - { - if ($cur_index['Key_name'] == ($no_prefix ? '' : $this->prefix).$table_name.'_'.$index_name) - { - $exists = true; - break; - } - } - - return $exists; - } - - - function create_table($table_name, $schema, $no_prefix = false) - { - if ($this->table_exists($table_name, $no_prefix)) - return true; - - $query = 'CREATE TABLE '.($no_prefix ? '' : $this->prefix).$table_name." (\n"; - - // Go through every schema element and add it to the query - foreach ($schema['FIELDS'] as $field_name => $field_data) - { - $field_data['datatype'] = preg_replace(array_keys($this->datatype_transformations), array_values($this->datatype_transformations), $field_data['datatype']); - - $query .= $field_name.' '.$field_data['datatype']; - - if (isset($field_data['collation'])) - $query .= 'CHARACTER SET utf8 COLLATE utf8_'.$field_data['collation']; - - if (!$field_data['allow_null']) - $query .= ' NOT NULL'; - - if (isset($field_data['default'])) - $query .= ' DEFAULT '.$field_data['default']; - - $query .= ",\n"; - } - - // If we have a primary key, add it - if (isset($schema['PRIMARY KEY'])) - $query .= 'PRIMARY KEY ('.implode(',', $schema['PRIMARY KEY']).'),'."\n"; - - // Add unique keys - if (isset($schema['UNIQUE KEYS'])) - { - foreach ($schema['UNIQUE KEYS'] as $key_name => $key_fields) - $query .= 'UNIQUE KEY '.($no_prefix ? '' : $this->prefix).$table_name.'_'.$key_name.'('.implode(',', $key_fields).'),'."\n"; - } - - // Add indexes - if (isset($schema['INDEXES'])) - { - foreach ($schema['INDEXES'] as $index_name => $index_fields) - $query .= 'KEY '.($no_prefix ? '' : $this->prefix).$table_name.'_'.$index_name.'('.implode(',', $index_fields).'),'."\n"; - } - - // We remove the last two characters (a newline and a comma) and add on the ending - $query = substr($query, 0, strlen($query) - 2)."\n".') ENGINE = '.(isset($schema['ENGINE']) ? $schema['ENGINE'] : 'MyISAM').' CHARACTER SET utf8'; - - return $this->query($query) ? true : false; - } - - - function drop_table($table_name, $no_prefix = false) - { - if (!$this->table_exists($table_name, $no_prefix)) - return true; - - return $this->query('DROP TABLE '.($no_prefix ? '' : $this->prefix).$table_name) ? true : false; - } - - - function add_field($table_name, $field_name, $field_type, $allow_null, $default_value = null, $after_field = null, $no_prefix = false) - { - if ($this->field_exists($table_name, $field_name, $no_prefix)) - return true; - - $field_type = preg_replace(array_keys($this->datatype_transformations), array_values($this->datatype_transformations), $field_type); - - if ($default_value !== null && !is_int($default_value) && !is_float($default_value)) - $default_value = '\''.$this->escape($default_value).'\''; - - return $this->query('ALTER TABLE '.($no_prefix ? '' : $this->prefix).$table_name.' ADD '.$field_name.' '.$field_type.($allow_null ? ' ' : ' NOT NULL').($default_value !== null ? ' DEFAULT '.$default_value : ' ').($after_field != null ? ' AFTER '.$after_field : '')) ? true : false; - } - - - function alter_field($table_name, $field_name, $field_type, $allow_null, $default_value = null, $after_field = null, $no_prefix = false) - { - if (!$this->field_exists($table_name, $field_name, $no_prefix)) - return true; - - $field_type = preg_replace(array_keys($this->datatype_transformations), array_values($this->datatype_transformations), $field_type); - - if ($default_value !== null && !is_int($default_value) && !is_float($default_value)) - $default_value = '\''.$this->escape($default_value).'\''; - - return $this->query('ALTER TABLE '.($no_prefix ? '' : $this->prefix).$table_name.' MODIFY '.$field_name.' '.$field_type.($allow_null ? ' ' : ' NOT NULL').($default_value !== null ? ' DEFAULT '.$default_value : ' ').($after_field != null ? ' AFTER '.$after_field : '')) ? true : false; - } - - - function drop_field($table_name, $field_name, $no_prefix = false) - { - if (!$this->field_exists($table_name, $field_name, $no_prefix)) - return true; - - return $this->query('ALTER TABLE '.($no_prefix ? '' : $this->prefix).$table_name.' DROP '.$field_name) ? true : false; - } - - - function add_index($table_name, $index_name, $index_fields, $unique = false, $no_prefix = false) - { - if ($this->index_exists($table_name, $index_name, $no_prefix)) - return true; - - return $this->query('ALTER TABLE '.($no_prefix ? '' : $this->prefix).$table_name.' ADD '.($unique ? 'UNIQUE ' : '').'INDEX '.($no_prefix ? '' : $this->prefix).$table_name.'_'.$index_name.' ('.implode(',', $index_fields).')') ? true : false; - } - - - function drop_index($table_name, $index_name, $no_prefix = false) - { - if (!$this->index_exists($table_name, $index_name, $no_prefix)) - return true; - - return $this->query('ALTER TABLE '.($no_prefix ? '' : $this->prefix).$table_name.' DROP INDEX '.($no_prefix ? '' : $this->prefix).$table_name.'_'.$index_name) ? true : false; - } - - function truncate_table($table_name, $no_prefix = false) - { - return $this->query('TRUNCATE TABLE '.($no_prefix ? '' : $this->prefix).$table_name) ? true : false; - } -} diff --git a/upload/include/dblayer/mysql_innodb.php b/upload/include/dblayer/mysql_innodb.php deleted file mode 100644 index b78c63c..0000000 --- a/upload/include/dblayer/mysql_innodb.php +++ /dev/null @@ -1,363 +0,0 @@ - 'INT(10) UNSIGNED AUTO_INCREMENT' - ); - - - function DBLayer($db_host, $db_username, $db_password, $db_name, $db_prefix, $p_connect) - { - $this->prefix = $db_prefix; - - if ($p_connect) - $this->link_id = @mysql_pconnect($db_host, $db_username, $db_password); - else - $this->link_id = @mysql_connect($db_host, $db_username, $db_password); - - if ($this->link_id) - { - if (!@mysql_select_db($db_name, $this->link_id)) - error('Unable to select database. MySQL reported: '.mysql_error(), __FILE__, __LINE__); - } - else - error('Unable to connect to MySQL server. MySQL reported: '.mysql_error(), __FILE__, __LINE__); - - // Setup the client-server character set (UTF-8) - if (!defined('FORUM_NO_SET_NAMES')) - $this->set_names('utf8'); - - return $this->link_id; - } - - - function start_transaction() - { - ++$this->in_transaction; - - mysql_query('START TRANSACTION', $this->link_id); - return; - } - - - function end_transaction() - { - --$this->in_transaction; - - mysql_query('COMMIT', $this->link_id); - return; - } - - - function query($sql, $unbuffered = false) - { - if (defined('PUN_SHOW_QUERIES')) - $q_start = get_microtime(); - - if ($unbuffered) - $this->query_result = @mysql_unbuffered_query($sql, $this->link_id); - else - $this->query_result = @mysql_query($sql, $this->link_id); - - if ($this->query_result) - { - if (defined('PUN_SHOW_QUERIES')) - $this->saved_queries[] = array($sql, sprintf('%.5f', get_microtime() - $q_start)); - - ++$this->num_queries; - - return $this->query_result; - } - else - { - if (defined('PUN_SHOW_QUERIES')) - $this->saved_queries[] = array($sql, 0); - - // Rollback transaction - if ($this->in_transaction) - mysql_query('ROLLBACK', $this->link_id); - - --$this->in_transaction; - - return false; - } - } - - - function result($query_id = 0, $row = 0, $col = 0) - { - return ($query_id) ? @mysql_result($query_id, $row, $col) : false; - } - - - function fetch_assoc($query_id = 0) - { - return ($query_id) ? @mysql_fetch_assoc($query_id) : false; - } - - - function fetch_row($query_id = 0) - { - return ($query_id) ? @mysql_fetch_row($query_id) : false; - } - - - function num_rows($query_id = 0) - { - return ($query_id) ? @mysql_num_rows($query_id) : false; - } - - - function affected_rows() - { - return ($this->link_id) ? @mysql_affected_rows($this->link_id) : false; - } - - - function insert_id() - { - return ($this->link_id) ? @mysql_insert_id($this->link_id) : false; - } - - - function get_num_queries() - { - return $this->num_queries; - } - - - function get_saved_queries() - { - return $this->saved_queries; - } - - - function free_result($query_id = false) - { - return ($query_id) ? @mysql_free_result($query_id) : false; - } - - - function escape($str) - { - if (is_array($str)) - return ''; - else if (function_exists('mysql_real_escape_string')) - return mysql_real_escape_string($str, $this->link_id); - else - return mysql_escape_string($str); - } - - - function error() - { - $result['error_sql'] = @current(@end($this->saved_queries)); - $result['error_no'] = @mysql_errno($this->link_id); - $result['error_msg'] = @mysql_error($this->link_id); - - return $result; - } - - - function close() - { - if ($this->link_id) - { - if ($this->query_result) - @mysql_free_result($this->query_result); - - return @mysql_close($this->link_id); - } - else - return false; - } - - - function set_names($names) - { - return $this->query('SET NAMES \''.$this->escape($names).'\''); - } - - - function get_version() - { - $result = $this->query('SELECT VERSION()'); - - return array( - 'name' => 'MySQL Standard (InnoDB)', - 'version' => preg_replace('/^([^-]+).*$/', '\\1', $this->result($result)) - ); - } - - - function table_exists($table_name, $no_prefix = false) - { - $result = $this->query('SHOW TABLES LIKE \''.($no_prefix ? '' : $this->prefix).$this->escape($table_name).'\''); - return $this->num_rows($result) > 0; - } - - - function field_exists($table_name, $field_name, $no_prefix = false) - { - $result = $this->query('SHOW COLUMNS FROM '.($no_prefix ? '' : $this->prefix).$table_name.' LIKE \''.$this->escape($field_name).'\''); - return $this->num_rows($result) > 0; - } - - - function index_exists($table_name, $index_name, $no_prefix = false) - { - $exists = false; - - $result = $this->query('SHOW INDEX FROM '.($no_prefix ? '' : $this->prefix).$table_name); - while ($cur_index = $this->fetch_assoc($result)) - { - if ($cur_index['Key_name'] == ($no_prefix ? '' : $this->prefix).$table_name.'_'.$index_name) - { - $exists = true; - break; - } - } - - return $exists; - } - - - function create_table($table_name, $schema, $no_prefix = false) - { - if ($this->table_exists($table_name, $no_prefix)) - return true; - - $query = 'CREATE TABLE '.($no_prefix ? '' : $this->prefix).$table_name." (\n"; - - // Go through every schema element and add it to the query - foreach ($schema['FIELDS'] as $field_name => $field_data) - { - $field_data['datatype'] = preg_replace(array_keys($this->datatype_transformations), array_values($this->datatype_transformations), $field_data['datatype']); - - $query .= $field_name.' '.$field_data['datatype']; - - if (isset($field_data['collation'])) - $query .= 'CHARACTER SET utf8 COLLATE utf8_'.$field_data['collation']; - - if (!$field_data['allow_null']) - $query .= ' NOT NULL'; - - if (isset($field_data['default'])) - $query .= ' DEFAULT '.$field_data['default']; - - $query .= ",\n"; - } - - // If we have a primary key, add it - if (isset($schema['PRIMARY KEY'])) - $query .= 'PRIMARY KEY ('.implode(',', $schema['PRIMARY KEY']).'),'."\n"; - - // Add unique keys - if (isset($schema['UNIQUE KEYS'])) - { - foreach ($schema['UNIQUE KEYS'] as $key_name => $key_fields) - $query .= 'UNIQUE KEY '.($no_prefix ? '' : $this->prefix).$table_name.'_'.$key_name.'('.implode(',', $key_fields).'),'."\n"; - } - - // Add indexes - if (isset($schema['INDEXES'])) - { - foreach ($schema['INDEXES'] as $index_name => $index_fields) - $query .= 'KEY '.($no_prefix ? '' : $this->prefix).$table_name.'_'.$index_name.'('.implode(',', $index_fields).'),'."\n"; - } - - // We remove the last two characters (a newline and a comma) and add on the ending - $query = substr($query, 0, strlen($query) - 2)."\n".') ENGINE = '.(isset($schema['ENGINE']) ? $schema['ENGINE'] : 'InnoDB').' CHARACTER SET utf8'; - - return $this->query($query) ? true : false; - } - - - function drop_table($table_name, $no_prefix = false) - { - if (!$this->table_exists($table_name, $no_prefix)) - return true; - - return $this->query('DROP TABLE '.($no_prefix ? '' : $this->prefix).$table_name) ? true : false; - } - - - function add_field($table_name, $field_name, $field_type, $allow_null, $default_value = null, $after_field = null, $no_prefix = false) - { - if ($this->field_exists($table_name, $field_name, $no_prefix)) - return true; - - $field_type = preg_replace(array_keys($this->datatype_transformations), array_values($this->datatype_transformations), $field_type); - - if ($default_value !== null && !is_int($default_value) && !is_float($default_value)) - $default_value = '\''.$this->escape($default_value).'\''; - - return $this->query('ALTER TABLE '.($no_prefix ? '' : $this->prefix).$table_name.' ADD '.$field_name.' '.$field_type.($allow_null ? ' ' : ' NOT NULL').($default_value !== null ? ' DEFAULT '.$default_value : ' ').($after_field != null ? ' AFTER '.$after_field : '')) ? true : false; - } - - - function alter_field($table_name, $field_name, $field_type, $allow_null, $default_value = null, $after_field = null, $no_prefix = false) - { - if (!$this->field_exists($table_name, $field_name, $no_prefix)) - return true; - - $field_type = preg_replace(array_keys($this->datatype_transformations), array_values($this->datatype_transformations), $field_type); - - if ($default_value !== null && !is_int($default_value) && !is_float($default_value)) - $default_value = '\''.$this->escape($default_value).'\''; - - return $this->query('ALTER TABLE '.($no_prefix ? '' : $this->prefix).$table_name.' MODIFY '.$field_name.' '.$field_type.($allow_null ? ' ' : ' NOT NULL').($default_value !== null ? ' DEFAULT '.$default_value : ' ').($after_field != null ? ' AFTER '.$after_field : '')) ? true : false; - } - - - function drop_field($table_name, $field_name, $no_prefix = false) - { - if (!$this->field_exists($table_name, $field_name, $no_prefix)) - return true; - - return $this->query('ALTER TABLE '.($no_prefix ? '' : $this->prefix).$table_name.' DROP '.$field_name) ? true : false; - } - - - function add_index($table_name, $index_name, $index_fields, $unique = false, $no_prefix = false) - { - if ($this->index_exists($table_name, $index_name, $no_prefix)) - return true; - - return $this->query('ALTER TABLE '.($no_prefix ? '' : $this->prefix).$table_name.' ADD '.($unique ? 'UNIQUE ' : '').'INDEX '.($no_prefix ? '' : $this->prefix).$table_name.'_'.$index_name.' ('.implode(',', $index_fields).')') ? true : false; - } - - - function drop_index($table_name, $index_name, $no_prefix = false) - { - if (!$this->index_exists($table_name, $index_name, $no_prefix)) - return true; - - return $this->query('ALTER TABLE '.($no_prefix ? '' : $this->prefix).$table_name.' DROP INDEX '.($no_prefix ? '' : $this->prefix).$table_name.'_'.$index_name) ? true : false; - } - - function truncate_table($table_name, $no_prefix = false) - { - return $this->query('TRUNCATE TABLE '.($no_prefix ? '' : $this->prefix).$table_name) ? true : false; - } -} diff --git a/upload/include/dblayer/mysqli.php b/upload/include/dblayer/mysqli.php deleted file mode 100644 index 9b81bdd..0000000 --- a/upload/include/dblayer/mysqli.php +++ /dev/null @@ -1,352 +0,0 @@ - 'INT(10) UNSIGNED AUTO_INCREMENT' - ); - - - function DBLayer($db_host, $db_username, $db_password, $db_name, $db_prefix, $p_connect) - { - $this->prefix = $db_prefix; - - // Was a custom port supplied with $db_host? - if (strpos($db_host, ':') !== false) - list($db_host, $db_port) = explode(':', $db_host); - - // Persistent connection in MySQLi are only available in PHP 5.3 and later releases - $p_connect = $p_connect && version_compare(PHP_VERSION, '5.3.0', '>=') ? 'p:' : ''; - - if (isset($db_port)) - $this->link_id = @mysqli_connect($p_connect.$db_host, $db_username, $db_password, $db_name, $db_port); - else - $this->link_id = @mysqli_connect($p_connect.$db_host, $db_username, $db_password, $db_name); - - if (!$this->link_id) - error('Unable to connect to MySQL and select database. MySQL reported: '.mysqli_connect_error(), __FILE__, __LINE__); - - // Setup the client-server character set (UTF-8) - if (!defined('FORUM_NO_SET_NAMES')) - $this->set_names('utf8'); - - return $this->link_id; - } - - - function start_transaction() - { - return; - } - - - function end_transaction() - { - return; - } - - - function query($sql, $unbuffered = false) - { - if (defined('PUN_SHOW_QUERIES')) - $q_start = get_microtime(); - - $this->query_result = @mysqli_query($this->link_id, $sql); - - if ($this->query_result) - { - if (defined('PUN_SHOW_QUERIES')) - $this->saved_queries[] = array($sql, sprintf('%.5f', get_microtime() - $q_start)); - - ++$this->num_queries; - - return $this->query_result; - } - else - { - if (defined('PUN_SHOW_QUERIES')) - $this->saved_queries[] = array($sql, 0); - - return false; - } - } - - - function result($query_id = 0, $row = 0, $col = 0) - { - if ($query_id) - { - if ($row) - @mysqli_data_seek($query_id, $row); - - $cur_row = @mysqli_fetch_row($query_id); - return $cur_row[$col]; - } - else - return false; - } - - - function fetch_assoc($query_id = 0) - { - return ($query_id) ? @mysqli_fetch_assoc($query_id) : false; - } - - - function fetch_row($query_id = 0) - { - return ($query_id) ? @mysqli_fetch_row($query_id) : false; - } - - - function num_rows($query_id = 0) - { - return ($query_id) ? @mysqli_num_rows($query_id) : false; - } - - - function affected_rows() - { - return ($this->link_id) ? @mysqli_affected_rows($this->link_id) : false; - } - - - function insert_id() - { - return ($this->link_id) ? @mysqli_insert_id($this->link_id) : false; - } - - - function get_num_queries() - { - return $this->num_queries; - } - - - function get_saved_queries() - { - return $this->saved_queries; - } - - - function free_result($query_id = false) - { - return ($query_id) ? @mysqli_free_result($query_id) : false; - } - - - function escape($str) - { - return is_array($str) ? '' : mysqli_real_escape_string($this->link_id, $str); - } - - - function error() - { - $result['error_sql'] = @current(@end($this->saved_queries)); - $result['error_no'] = @mysqli_errno($this->link_id); - $result['error_msg'] = @mysqli_error($this->link_id); - - return $result; - } - - - function close() - { - if ($this->link_id) - { - if ($this->query_result) - @mysqli_free_result($this->query_result); - - return @mysqli_close($this->link_id); - } - else - return false; - } - - function set_names($names) - { - return $this->query('SET NAMES \''.$this->escape($names).'\''); - } - - - function get_version() - { - $result = $this->query('SELECT VERSION()'); - - return array( - 'name' => 'MySQL Improved', - 'version' => preg_replace('/^([^-]+).*$/', '\\1', $this->result($result)) - ); - } - - - function table_exists($table_name, $no_prefix = false) - { - $result = $this->query('SHOW TABLES LIKE \''.($no_prefix ? '' : $this->prefix).$this->escape($table_name).'\''); - return $this->num_rows($result) > 0; - } - - - function field_exists($table_name, $field_name, $no_prefix = false) - { - $result = $this->query('SHOW COLUMNS FROM '.($no_prefix ? '' : $this->prefix).$table_name.' LIKE \''.$this->escape($field_name).'\''); - return $this->num_rows($result) > 0; - } - - - function index_exists($table_name, $index_name, $no_prefix = false) - { - $exists = false; - - $result = $this->query('SHOW INDEX FROM '.($no_prefix ? '' : $this->prefix).$table_name); - while ($cur_index = $this->fetch_assoc($result)) - { - if ($cur_index['Key_name'] == ($no_prefix ? '' : $this->prefix).$table_name.'_'.$index_name) - { - $exists = true; - break; - } - } - - return $exists; - } - - - function create_table($table_name, $schema, $no_prefix = false) - { - if ($this->table_exists($table_name, $no_prefix)) - return true; - - $query = 'CREATE TABLE '.($no_prefix ? '' : $this->prefix).$table_name." (\n"; - - // Go through every schema element and add it to the query - foreach ($schema['FIELDS'] as $field_name => $field_data) - { - $field_data['datatype'] = preg_replace(array_keys($this->datatype_transformations), array_values($this->datatype_transformations), $field_data['datatype']); - - $query .= $field_name.' '.$field_data['datatype']; - - if (isset($field_data['collation'])) - $query .= 'CHARACTER SET utf8 COLLATE utf8_'.$field_data['collation']; - - if (!$field_data['allow_null']) - $query .= ' NOT NULL'; - - if (isset($field_data['default'])) - $query .= ' DEFAULT '.$field_data['default']; - - $query .= ",\n"; - } - - // If we have a primary key, add it - if (isset($schema['PRIMARY KEY'])) - $query .= 'PRIMARY KEY ('.implode(',', $schema['PRIMARY KEY']).'),'."\n"; - - // Add unique keys - if (isset($schema['UNIQUE KEYS'])) - { - foreach ($schema['UNIQUE KEYS'] as $key_name => $key_fields) - $query .= 'UNIQUE KEY '.($no_prefix ? '' : $this->prefix).$table_name.'_'.$key_name.'('.implode(',', $key_fields).'),'."\n"; - } - - // Add indexes - if (isset($schema['INDEXES'])) - { - foreach ($schema['INDEXES'] as $index_name => $index_fields) - $query .= 'KEY '.($no_prefix ? '' : $this->prefix).$table_name.'_'.$index_name.'('.implode(',', $index_fields).'),'."\n"; - } - - // We remove the last two characters (a newline and a comma) and add on the ending - $query = substr($query, 0, strlen($query) - 2)."\n".') ENGINE = '.(isset($schema['ENGINE']) ? $schema['ENGINE'] : 'MyISAM').' CHARACTER SET utf8'; - - return $this->query($query) ? true : false; - } - - - function drop_table($table_name, $no_prefix = false) - { - if (!$this->table_exists($table_name, $no_prefix)) - return true; - - return $this->query('DROP TABLE '.($no_prefix ? '' : $this->prefix).$table_name) ? true : false; - } - - - function add_field($table_name, $field_name, $field_type, $allow_null, $default_value = null, $after_field = null, $no_prefix = false) - { - if ($this->field_exists($table_name, $field_name, $no_prefix)) - return true; - - $field_type = preg_replace(array_keys($this->datatype_transformations), array_values($this->datatype_transformations), $field_type); - - if ($default_value !== null && !is_int($default_value) && !is_float($default_value)) - $default_value = '\''.$this->escape($default_value).'\''; - - return $this->query('ALTER TABLE '.($no_prefix ? '' : $this->prefix).$table_name.' ADD '.$field_name.' '.$field_type.($allow_null ? ' ' : ' NOT NULL').($default_value !== null ? ' DEFAULT '.$default_value : ' ').($after_field != null ? ' AFTER '.$after_field : '')) ? true : false; - } - - - function alter_field($table_name, $field_name, $field_type, $allow_null, $default_value = null, $after_field = null, $no_prefix = false) - { - if (!$this->field_exists($table_name, $field_name, $no_prefix)) - return true; - - $field_type = preg_replace(array_keys($this->datatype_transformations), array_values($this->datatype_transformations), $field_type); - - if ($default_value !== null && !is_int($default_value) && !is_float($default_value)) - $default_value = '\''.$this->escape($default_value).'\''; - - return $this->query('ALTER TABLE '.($no_prefix ? '' : $this->prefix).$table_name.' MODIFY '.$field_name.' '.$field_type.($allow_null ? ' ' : ' NOT NULL').($default_value !== null ? ' DEFAULT '.$default_value : ' ').($after_field != null ? ' AFTER '.$after_field : '')) ? true : false; - } - - - function drop_field($table_name, $field_name, $no_prefix = false) - { - if (!$this->field_exists($table_name, $field_name, $no_prefix)) - return true; - - return $this->query('ALTER TABLE '.($no_prefix ? '' : $this->prefix).$table_name.' DROP '.$field_name) ? true : false; - } - - - function add_index($table_name, $index_name, $index_fields, $unique = false, $no_prefix = false) - { - if ($this->index_exists($table_name, $index_name, $no_prefix)) - return true; - - return $this->query('ALTER TABLE '.($no_prefix ? '' : $this->prefix).$table_name.' ADD '.($unique ? 'UNIQUE ' : '').'INDEX '.($no_prefix ? '' : $this->prefix).$table_name.'_'.$index_name.' ('.implode(',', $index_fields).')') ? true : false; - } - - - function drop_index($table_name, $index_name, $no_prefix = false) - { - if (!$this->index_exists($table_name, $index_name, $no_prefix)) - return true; - - return $this->query('ALTER TABLE '.($no_prefix ? '' : $this->prefix).$table_name.' DROP INDEX '.($no_prefix ? '' : $this->prefix).$table_name.'_'.$index_name) ? true : false; - } - - function truncate_table($table_name, $no_prefix = false) - { - return $this->query('TRUNCATE TABLE '.($no_prefix ? '' : $this->prefix).$table_name) ? true : false; - } -} diff --git a/upload/include/dblayer/mysqli_innodb.php b/upload/include/dblayer/mysqli_innodb.php deleted file mode 100644 index 2b591cd..0000000 --- a/upload/include/dblayer/mysqli_innodb.php +++ /dev/null @@ -1,366 +0,0 @@ - 'INT(10) UNSIGNED AUTO_INCREMENT' - ); - - - function DBLayer($db_host, $db_username, $db_password, $db_name, $db_prefix, $p_connect) - { - $this->prefix = $db_prefix; - - // Was a custom port supplied with $db_host? - if (strpos($db_host, ':') !== false) - list($db_host, $db_port) = explode(':', $db_host); - - // Persistent connection in MySQLi are only available in PHP 5.3 and later releases - $p_connect = $p_connect && version_compare(PHP_VERSION, '5.3.0', '>=') ? 'p:' : ''; - - if (isset($db_port)) - $this->link_id = @mysqli_connect($p_connect.$db_host, $db_username, $db_password, $db_name, $db_port); - else - $this->link_id = @mysqli_connect($p_connect.$db_host, $db_username, $db_password, $db_name); - - if (!$this->link_id) - error('Unable to connect to MySQL and select database. MySQL reported: '.mysqli_connect_error(), __FILE__, __LINE__); - - // Setup the client-server character set (UTF-8) - if (!defined('FORUM_NO_SET_NAMES')) - $this->set_names('utf8'); - - return $this->link_id; - } - - - function start_transaction() - { - ++$this->in_transaction; - - mysqli_query($this->link_id, 'START TRANSACTION'); - return; - } - - - function end_transaction() - { - --$this->in_transaction; - - mysqli_query($this->link_id, 'COMMIT'); - return; - } - - - function query($sql, $unbuffered = false) - { - if (defined('PUN_SHOW_QUERIES')) - $q_start = get_microtime(); - - $this->query_result = @mysqli_query($this->link_id, $sql); - - if ($this->query_result) - { - if (defined('PUN_SHOW_QUERIES')) - $this->saved_queries[] = array($sql, sprintf('%.5f', get_microtime() - $q_start)); - - ++$this->num_queries; - - return $this->query_result; - } - else - { - if (defined('PUN_SHOW_QUERIES')) - $this->saved_queries[] = array($sql, 0); - - // Rollback transaction - if ($this->in_transaction) - mysqli_query($this->link_id, 'ROLLBACK'); - - --$this->in_transaction; - - return false; - } - } - - - function result($query_id = 0, $row = 0, $col = 0) - { - if ($query_id) - { - if ($row) - @mysqli_data_seek($query_id, $row); - - $cur_row = @mysqli_fetch_row($query_id); - return $cur_row[$col]; - } - else - return false; - } - - - function fetch_assoc($query_id = 0) - { - return ($query_id) ? @mysqli_fetch_assoc($query_id) : false; - } - - - function fetch_row($query_id = 0) - { - return ($query_id) ? @mysqli_fetch_row($query_id) : false; - } - - - function num_rows($query_id = 0) - { - return ($query_id) ? @mysqli_num_rows($query_id) : false; - } - - - function affected_rows() - { - return ($this->link_id) ? @mysqli_affected_rows($this->link_id) : false; - } - - - function insert_id() - { - return ($this->link_id) ? @mysqli_insert_id($this->link_id) : false; - } - - - function get_num_queries() - { - return $this->num_queries; - } - - - function get_saved_queries() - { - return $this->saved_queries; - } - - - function free_result($query_id = false) - { - return ($query_id) ? @mysqli_free_result($query_id) : false; - } - - - function escape($str) - { - return is_array($str) ? '' : mysqli_real_escape_string($this->link_id, $str); - } - - - function error() - { - $result['error_sql'] = @current(@end($this->saved_queries)); - $result['error_no'] = @mysqli_errno($this->link_id); - $result['error_msg'] = @mysqli_error($this->link_id); - - return $result; - } - - - function close() - { - if ($this->link_id) - { - if ($this->query_result) - @mysqli_free_result($this->query_result); - - return @mysqli_close($this->link_id); - } - else - return false; - } - - - function set_names($names) - { - return $this->query('SET NAMES \''.$this->escape($names).'\''); - } - - - function get_version() - { - $result = $this->query('SELECT VERSION()'); - - return array( - 'name' => 'MySQL Improved (InnoDB)', - 'version' => preg_replace('/^([^-]+).*$/', '\\1', $this->result($result)) - ); - } - - - function table_exists($table_name, $no_prefix = false) - { - $result = $this->query('SHOW TABLES LIKE \''.($no_prefix ? '' : $this->prefix).$this->escape($table_name).'\''); - return $this->num_rows($result) > 0; - } - - - function field_exists($table_name, $field_name, $no_prefix = false) - { - $result = $this->query('SHOW COLUMNS FROM '.($no_prefix ? '' : $this->prefix).$table_name.' LIKE \''.$this->escape($field_name).'\''); - return $this->num_rows($result) > 0; - } - - - function index_exists($table_name, $index_name, $no_prefix = false) - { - $exists = false; - - $result = $this->query('SHOW INDEX FROM '.($no_prefix ? '' : $this->prefix).$table_name); - while ($cur_index = $this->fetch_assoc($result)) - { - if ($cur_index['Key_name'] == ($no_prefix ? '' : $this->prefix).$table_name.'_'.$index_name) - { - $exists = true; - break; - } - } - - return $exists; - } - - - function create_table($table_name, $schema, $no_prefix = false) - { - if ($this->table_exists($table_name, $no_prefix)) - return true; - - $query = 'CREATE TABLE '.($no_prefix ? '' : $this->prefix).$table_name." (\n"; - - // Go through every schema element and add it to the query - foreach ($schema['FIELDS'] as $field_name => $field_data) - { - $field_data['datatype'] = preg_replace(array_keys($this->datatype_transformations), array_values($this->datatype_transformations), $field_data['datatype']); - - $query .= $field_name.' '.$field_data['datatype']; - - if (isset($field_data['collation'])) - $query .= 'CHARACTER SET utf8 COLLATE utf8_'.$field_data['collation']; - - if (!$field_data['allow_null']) - $query .= ' NOT NULL'; - - if (isset($field_data['default'])) - $query .= ' DEFAULT '.$field_data['default']; - - $query .= ",\n"; - } - - // If we have a primary key, add it - if (isset($schema['PRIMARY KEY'])) - $query .= 'PRIMARY KEY ('.implode(',', $schema['PRIMARY KEY']).'),'."\n"; - - // Add unique keys - if (isset($schema['UNIQUE KEYS'])) - { - foreach ($schema['UNIQUE KEYS'] as $key_name => $key_fields) - $query .= 'UNIQUE KEY '.($no_prefix ? '' : $this->prefix).$table_name.'_'.$key_name.'('.implode(',', $key_fields).'),'."\n"; - } - - // Add indexes - if (isset($schema['INDEXES'])) - { - foreach ($schema['INDEXES'] as $index_name => $index_fields) - $query .= 'KEY '.($no_prefix ? '' : $this->prefix).$table_name.'_'.$index_name.'('.implode(',', $index_fields).'),'."\n"; - } - - // We remove the last two characters (a newline and a comma) and add on the ending - $query = substr($query, 0, strlen($query) - 2)."\n".') ENGINE = '.(isset($schema['ENGINE']) ? $schema['ENGINE'] : 'InnoDB').' CHARACTER SET utf8'; - - return $this->query($query) ? true : false; - } - - - function drop_table($table_name, $no_prefix = false) - { - if (!$this->table_exists($table_name, $no_prefix)) - return true; - - return $this->query('DROP TABLE '.($no_prefix ? '' : $this->prefix).$table_name) ? true : false; - } - - - function add_field($table_name, $field_name, $field_type, $allow_null, $default_value = null, $after_field = null, $no_prefix = false) - { - if ($this->field_exists($table_name, $field_name, $no_prefix)) - return true; - - $field_type = preg_replace(array_keys($this->datatype_transformations), array_values($this->datatype_transformations), $field_type); - - if ($default_value !== null && !is_int($default_value) && !is_float($default_value)) - $default_value = '\''.$this->escape($default_value).'\''; - - return $this->query('ALTER TABLE '.($no_prefix ? '' : $this->prefix).$table_name.' ADD '.$field_name.' '.$field_type.($allow_null ? ' ' : ' NOT NULL').($default_value !== null ? ' DEFAULT '.$default_value : ' ').($after_field != null ? ' AFTER '.$after_field : '')) ? true : false; - } - - - function alter_field($table_name, $field_name, $field_type, $allow_null, $default_value = null, $after_field = null, $no_prefix = false) - { - if (!$this->field_exists($table_name, $field_name, $no_prefix)) - return true; - - $field_type = preg_replace(array_keys($this->datatype_transformations), array_values($this->datatype_transformations), $field_type); - - if ($default_value !== null && !is_int($default_value) && !is_float($default_value)) - $default_value = '\''.$this->escape($default_value).'\''; - - return $this->query('ALTER TABLE '.($no_prefix ? '' : $this->prefix).$table_name.' MODIFY '.$field_name.' '.$field_type.($allow_null ? ' ' : ' NOT NULL').($default_value !== null ? ' DEFAULT '.$default_value : ' ').($after_field != null ? ' AFTER '.$after_field : '')) ? true : false; - } - - - function drop_field($table_name, $field_name, $no_prefix = false) - { - if (!$this->field_exists($table_name, $field_name, $no_prefix)) - return true; - - return $this->query('ALTER TABLE '.($no_prefix ? '' : $this->prefix).$table_name.' DROP '.$field_name) ? true : false; - } - - - function add_index($table_name, $index_name, $index_fields, $unique = false, $no_prefix = false) - { - if ($this->index_exists($table_name, $index_name, $no_prefix)) - return true; - - return $this->query('ALTER TABLE '.($no_prefix ? '' : $this->prefix).$table_name.' ADD '.($unique ? 'UNIQUE ' : '').'INDEX '.($no_prefix ? '' : $this->prefix).$table_name.'_'.$index_name.' ('.implode(',', $index_fields).')') ? true : false; - } - - - function drop_index($table_name, $index_name, $no_prefix = false) - { - if (!$this->index_exists($table_name, $index_name, $no_prefix)) - return true; - - return $this->query('ALTER TABLE '.($no_prefix ? '' : $this->prefix).$table_name.' DROP INDEX '.($no_prefix ? '' : $this->prefix).$table_name.'_'.$index_name) ? true : false; - } - - function truncate_table($table_name, $no_prefix = false) - { - return $this->query('TRUNCATE TABLE '.($no_prefix ? '' : $this->prefix).$table_name) ? true : false; - } -} diff --git a/upload/include/dblayer/pgsql.php b/upload/include/dblayer/pgsql.php deleted file mode 100644 index 05d8cf0..0000000 --- a/upload/include/dblayer/pgsql.php +++ /dev/null @@ -1,427 +0,0 @@ - 'SMALLINT', - '/^(MEDIUM)?INT( )?(\\([0-9]+\\))?( )?(UNSIGNED)?$/i' => 'INTEGER', - '/^BIGINT( )?(\\([0-9]+\\))?( )?(UNSIGNED)?$/i' => 'BIGINT', - '/^(TINY|MEDIUM|LONG)?TEXT$/i' => 'TEXT', - '/^DOUBLE( )?(\\([0-9,]+\\))?( )?(UNSIGNED)?$/i' => 'DOUBLE PRECISION', - '/^FLOAT( )?(\\([0-9]+\\))?( )?(UNSIGNED)?$/i' => 'REAL' - ); - - - function DBLayer($db_host, $db_username, $db_password, $db_name, $db_prefix, $p_connect) - { - $this->prefix = $db_prefix; - - if ($db_host) - { - if (strpos($db_host, ':') !== false) - { - list($db_host, $dbport) = explode(':', $db_host); - $connect_str[] = 'host='.$db_host.' port='.$dbport; - } - else - $connect_str[] = 'host='.$db_host; - } - - if ($db_name) - $connect_str[] = 'dbname='.$db_name; - - if ($db_username) - $connect_str[] = 'user='.$db_username; - - if ($db_password) - $connect_str[] = 'password='.$db_password; - - if ($p_connect) - $this->link_id = @pg_pconnect(implode(' ', $connect_str)); - else - $this->link_id = @pg_connect(implode(' ', $connect_str)); - - if (!$this->link_id) - error('Unable to connect to PostgreSQL server', __FILE__, __LINE__); - - // Setup the client-server character set (UTF-8) - if (!defined('FORUM_NO_SET_NAMES')) - $this->set_names('utf8'); - - return $this->link_id; - } - - - function start_transaction() - { - ++$this->in_transaction; - - return (@pg_query($this->link_id, 'BEGIN')) ? true : false; - } - - - function end_transaction() - { - --$this->in_transaction; - - if (@pg_query($this->link_id, 'COMMIT')) - return true; - else - { - @pg_query($this->link_id, 'ROLLBACK'); - return false; - } - } - - - function query($sql, $unbuffered = false) // $unbuffered is ignored since there is no pgsql_unbuffered_query() - { - if (strrpos($sql, 'LIMIT') !== false) - $sql = preg_replace('#LIMIT ([0-9]+),([ 0-9]+)#', 'LIMIT \\2 OFFSET \\1', $sql); - - if (defined('PUN_SHOW_QUERIES')) - $q_start = get_microtime(); - - @pg_send_query($this->link_id, $sql); - $this->query_result = @pg_get_result($this->link_id); - - if (pg_result_status($this->query_result) != PGSQL_FATAL_ERROR) - { - if (defined('PUN_SHOW_QUERIES')) - $this->saved_queries[] = array($sql, sprintf('%.5f', get_microtime() - $q_start)); - - ++$this->num_queries; - - $this->last_query_text[$this->query_result] = $sql; - - return $this->query_result; - } - else - { - if (defined('PUN_SHOW_QUERIES')) - $this->saved_queries[] = array($sql, 0); - - $this->error_msg = @pg_result_error($this->query_result); - - if ($this->in_transaction) - @pg_query($this->link_id, 'ROLLBACK'); - - --$this->in_transaction; - - return false; - } - } - - - function result($query_id = 0, $row = 0, $col = 0) - { - return ($query_id) ? @pg_fetch_result($query_id, $row, $col) : false; - } - - - function fetch_assoc($query_id = 0) - { - return ($query_id) ? @pg_fetch_assoc($query_id) : false; - } - - - function fetch_row($query_id = 0) - { - return ($query_id) ? @pg_fetch_row($query_id) : false; - } - - - function num_rows($query_id = 0) - { - return ($query_id) ? @pg_num_rows($query_id) : false; - } - - - function affected_rows() - { - return ($this->query_result) ? @pg_affected_rows($this->query_result) : false; - } - - - function insert_id() - { - $query_id = $this->query_result; - - if ($query_id && $this->last_query_text[$query_id] != '') - { - if (preg_match('/^INSERT INTO ([a-z0-9\_\-]+)/is', $this->last_query_text[$query_id], $table_name)) - { - // Hack (don't ask) - if (substr($table_name[1], -6) == 'groups') - $table_name[1] .= '_g'; - - $temp_q_id = @pg_query($this->link_id, 'SELECT currval(\''.$table_name[1].'_id_seq\')'); - return ($temp_q_id) ? intval(@pg_fetch_result($temp_q_id, 0)) : false; - } - } - - return false; - } - - - function get_num_queries() - { - return $this->num_queries; - } - - - function get_saved_queries() - { - return $this->saved_queries; - } - - - function free_result($query_id = false) - { - if (!$query_id) - $query_id = $this->query_result; - - return ($query_id) ? @pg_free_result($query_id) : false; - } - - - function escape($str) - { - return is_array($str) ? '' : pg_escape_string($str); - } - - - function error() - { - $result['error_sql'] = @current(@end($this->saved_queries)); - $result['error_no'] = false; -/* - if (!empty($this->query_result)) - { - $result['error_msg'] = trim(@pg_result_error($this->query_result)); - if ($result['error_msg'] != '') - return $result; - } - - $result['error_msg'] = (!empty($this->link_id)) ? trim(@pg_last_error($this->link_id)) : trim(@pg_last_error()); -*/ - $result['error_msg'] = $this->error_msg; - - return $result; - } - - - function close() - { - if ($this->link_id) - { - if ($this->in_transaction) - { - if (defined('PUN_SHOW_QUERIES')) - $this->saved_queries[] = array('COMMIT', 0); - - @pg_query($this->link_id, 'COMMIT'); - } - - if ($this->query_result) - @pg_free_result($this->query_result); - - return @pg_close($this->link_id); - } - else - return false; - } - - function set_names($names) - { - return $this->query('SET NAMES \''.$this->escape($names).'\''); - } - - - function get_version() - { - $result = $this->query('SELECT VERSION()'); - - return array( - 'name' => 'PostgreSQL', - 'version' => preg_replace('/^[^0-9]+([^\s,-]+).*$/', '\\1', $this->result($result)) - ); - } - - - function table_exists($table_name, $no_prefix = false) - { - $result = $this->query('SELECT 1 FROM pg_class WHERE relname = \''.($no_prefix ? '' : $this->prefix).$this->escape($table_name).'\''); - return $this->num_rows($result) > 0; - } - - - function field_exists($table_name, $field_name, $no_prefix = false) - { - $result = $this->query('SELECT 1 FROM pg_class c INNER JOIN pg_attribute a ON a.attrelid = c.oid WHERE c.relname = \''.($no_prefix ? '' : $this->prefix).$this->escape($table_name).'\' AND a.attname = \''.$this->escape($field_name).'\''); - return $this->num_rows($result) > 0; - } - - - function index_exists($table_name, $index_name, $no_prefix = false) - { - $result = $this->query('SELECT 1 FROM pg_index i INNER JOIN pg_class c1 ON c1.oid = i.indrelid INNER JOIN pg_class c2 ON c2.oid = i.indexrelid WHERE c1.relname = \''.($no_prefix ? '' : $this->prefix).$this->escape($table_name).'\' AND c2.relname = \''.($no_prefix ? '' : $this->prefix).$this->escape($table_name).'_'.$this->escape($index_name).'\''); - return $this->num_rows($result) > 0; - } - - - function create_table($table_name, $schema, $no_prefix = false) - { - if ($this->table_exists($table_name, $no_prefix)) - return true; - - $query = 'CREATE TABLE '.($no_prefix ? '' : $this->prefix).$table_name." (\n"; - - // Go through every schema element and add it to the query - foreach ($schema['FIELDS'] as $field_name => $field_data) - { - $field_data['datatype'] = preg_replace(array_keys($this->datatype_transformations), array_values($this->datatype_transformations), $field_data['datatype']); - - $query .= $field_name.' '.$field_data['datatype']; - - // The SERIAL datatype is a special case where we don't need to say not null - if (!$field_data['allow_null'] && $field_data['datatype'] != 'SERIAL') - $query .= ' NOT NULL'; - - if (isset($field_data['default'])) - $query .= ' DEFAULT '.$field_data['default']; - - $query .= ",\n"; - } - - // If we have a primary key, add it - if (isset($schema['PRIMARY KEY'])) - $query .= 'PRIMARY KEY ('.implode(',', $schema['PRIMARY KEY']).'),'."\n"; - - // Add unique keys - if (isset($schema['UNIQUE KEYS'])) - { - foreach ($schema['UNIQUE KEYS'] as $key_name => $key_fields) - $query .= 'UNIQUE ('.implode(',', $key_fields).'),'."\n"; - } - - // We remove the last two characters (a newline and a comma) and add on the ending - $query = substr($query, 0, strlen($query) - 2)."\n".')'; - - $result = $this->query($query) ? true : false; - - // Add indexes - if (isset($schema['INDEXES'])) - { - foreach ($schema['INDEXES'] as $index_name => $index_fields) - $result &= $this->add_index($table_name, $index_name, $index_fields, false, $no_prefix); - } - - return $result; - } - - - function drop_table($table_name, $no_prefix = false) - { - if (!$this->table_exists($table_name, $no_prefix)) - return true; - - return $this->query('DROP TABLE '.($no_prefix ? '' : $this->prefix).$table_name) ? true : false; - } - - - function add_field($table_name, $field_name, $field_type, $allow_null, $default_value = null, $after_field = null, $no_prefix = false) - { - if ($this->field_exists($table_name, $field_name, $no_prefix)) - return true; - - $field_type = preg_replace(array_keys($this->datatype_transformations), array_values($this->datatype_transformations), $field_type); - - $result = $this->query('ALTER TABLE '.($no_prefix ? '' : $this->prefix).$table_name.' ADD '.$field_name.' '.$field_type) ? true : false; - - if ($default_value !== null) - { - if (!is_int($default_value) && !is_float($default_value)) - $default_value = '\''.$this->escape($default_value).'\''; - - $result &= $this->query('ALTER TABLE '.($no_prefix ? '' : $this->prefix).$table_name.' ALTER '.$field_name.' SET DEFAULT '.$default_value) ? true : false; - $result &= $this->query('UPDATE '.($no_prefix ? '' : $this->prefix).$table_name.' SET '.$field_name.'='.$default_value) ? true : false; - } - - if (!$allow_null) - $result &= $this->query('ALTER TABLE '.($no_prefix ? '' : $this->prefix).$table_name.' ALTER '.$field_name.' SET NOT NULL') ? true : false; - - return $result; - } - - - function alter_field($table_name, $field_name, $field_type, $allow_null, $default_value = null, $after_field = null, $no_prefix = false) - { - if (!$this->field_exists($table_name, $field_name, $no_prefix)) - return true; - - $field_type = preg_replace(array_keys($this->datatype_transformations), array_values($this->datatype_transformations), $field_type); - - $result = $this->add_field($table_name, 'tmp_'.$field_name, $field_type, $allow_null, $default_value, $after_field, $no_prefix); - $result &= $this->query('UPDATE '.($no_prefix ? '' : $this->prefix).$table_name.' SET tmp_'.$field_name.' = '.$field_name) ? true : false; - $result &= $this->drop_field($table_name, $field_name, $no_prefix); - $result &= $this->query('ALTER TABLE '.($no_prefix ? '' : $this->prefix).$table_name.' RENAME COLUMN tmp_'.$field_name.' TO '.$field_name) ? true : false; - - return $result; - } - - - function drop_field($table_name, $field_name, $no_prefix = false) - { - if (!$this->field_exists($table_name, $field_name, $no_prefix)) - return true; - - return $this->query('ALTER TABLE '.($no_prefix ? '' : $this->prefix).$table_name.' DROP '.$field_name) ? true : false; - } - - - function add_index($table_name, $index_name, $index_fields, $unique = false, $no_prefix = false) - { - if ($this->index_exists($table_name, $index_name, $no_prefix)) - return true; - - return $this->query('CREATE '.($unique ? 'UNIQUE ' : '').'INDEX '.($no_prefix ? '' : $this->prefix).$table_name.'_'.$index_name.' ON '.($no_prefix ? '' : $this->prefix).$table_name.'('.implode(',', $index_fields).')') ? true : false; - } - - - function drop_index($table_name, $index_name, $no_prefix = false) - { - if (!$this->index_exists($table_name, $index_name, $no_prefix)) - return true; - - return $this->query('DROP INDEX '.($no_prefix ? '' : $this->prefix).$table_name.'_'.$index_name) ? true : false; - } - - function truncate_table($table_name, $no_prefix = false) - { - return $this->query('DELETE FROM '.($no_prefix ? '' : $this->prefix).$table_name) ? true : false; - } -} diff --git a/upload/include/dblayer/sqlite.php b/upload/include/dblayer/sqlite.php deleted file mode 100644 index 49ffeb8..0000000 --- a/upload/include/dblayer/sqlite.php +++ /dev/null @@ -1,528 +0,0 @@ - 'INTEGER', - '/^(TINY|SMALL|MEDIUM|BIG)?INT( )?(\\([0-9]+\\))?( )?(UNSIGNED)?$/i' => 'INTEGER', - '/^(TINY|MEDIUM|LONG)?TEXT$/i' => 'TEXT' - ); - - - function DBLayer($db_host, $db_username, $db_password, $db_name, $db_prefix, $p_connect) - { - // Prepend $db_name with the path to the forum root directory - $db_name = PUN_ROOT.$db_name; - - $this->prefix = $db_prefix; - - if (!file_exists($db_name)) - { - @touch($db_name); - @chmod($db_name, 0666); - if (!file_exists($db_name)) - error('Unable to create new database \''.$db_name.'\'. Permission denied', __FILE__, __LINE__); - } - - if (!is_readable($db_name)) - error('Unable to open database \''.$db_name.'\' for reading. Permission denied', __FILE__, __LINE__); - - if (!is_writable($db_name)) - error('Unable to open database \''.$db_name.'\' for writing. Permission denied', __FILE__, __LINE__); - - if ($p_connect) - $this->link_id = @sqlite_popen($db_name, 0666, $sqlite_error); - else - $this->link_id = @sqlite_open($db_name, 0666, $sqlite_error); - - if (!$this->link_id) - error('Unable to open database \''.$db_name.'\'. SQLite reported: '.$sqlite_error, __FILE__, __LINE__); - else - return $this->link_id; - } - - - function start_transaction() - { - ++$this->in_transaction; - - return (@sqlite_query($this->link_id, 'BEGIN')) ? true : false; - } - - - function end_transaction() - { - --$this->in_transaction; - - if (@sqlite_query($this->link_id, 'COMMIT')) - return true; - else - { - @sqlite_query($this->link_id, 'ROLLBACK'); - return false; - } - } - - - function query($sql, $unbuffered = false) - { - if (defined('PUN_SHOW_QUERIES')) - $q_start = get_microtime(); - - if ($unbuffered) - $this->query_result = @sqlite_unbuffered_query($this->link_id, $sql); - else - $this->query_result = @sqlite_query($this->link_id, $sql); - - if ($this->query_result) - { - if (defined('PUN_SHOW_QUERIES')) - $this->saved_queries[] = array($sql, sprintf('%.5f', get_microtime() - $q_start)); - - ++$this->num_queries; - - return $this->query_result; - } - else - { - if (defined('PUN_SHOW_QUERIES')) - $this->saved_queries[] = array($sql, 0); - - $this->error_no = @sqlite_last_error($this->link_id); - $this->error_msg = @sqlite_error_string($this->error_no); - - if ($this->in_transaction) - @sqlite_query($this->link_id, 'ROLLBACK'); - - --$this->in_transaction; - - return false; - } - } - - - function result($query_id = 0, $row = 0, $col = 0) - { - if ($query_id) - { - if ($row != 0) - @sqlite_seek($query_id, $row); - - $cur_row = @sqlite_current($query_id); - return $cur_row[$col]; - } - else - return false; - } - - - function fetch_assoc($query_id = 0) - { - if ($query_id) - { - $cur_row = @sqlite_fetch_array($query_id, SQLITE_ASSOC); - if ($cur_row) - { - // Horrible hack to get rid of table names and table aliases from the array keys - foreach ($cur_row as $key => $value) - { - $dot_spot = strpos($key, '.'); - if ($dot_spot !== false) - { - unset($cur_row[$key]); - $key = substr($key, $dot_spot+1); - $cur_row[$key] = $value; - } - } - } - - return $cur_row; - } - else - return false; - } - - - function fetch_row($query_id = 0) - { - return ($query_id) ? @sqlite_fetch_array($query_id, SQLITE_NUM) : false; - } - - - function num_rows($query_id = 0) - { - return ($query_id) ? @sqlite_num_rows($query_id) : false; - } - - - function affected_rows() - { - return ($this->query_result) ? @sqlite_changes($this->query_result) : false; - } - - - function insert_id() - { - return ($this->link_id) ? @sqlite_last_insert_rowid($this->link_id) : false; - } - - - function get_num_queries() - { - return $this->num_queries; - } - - - function get_saved_queries() - { - return $this->saved_queries; - } - - - function free_result($query_id = false) - { - return true; - } - - - function escape($str) - { - return is_array($str) ? '' : sqlite_escape_string($str); - } - - - function error() - { - $result['error_sql'] = @current(@end($this->saved_queries)); - $result['error_no'] = $this->error_no; - $result['error_msg'] = $this->error_msg; - - return $result; - } - - - function close() - { - if ($this->link_id) - { - if ($this->in_transaction) - { - if (defined('PUN_SHOW_QUERIES')) - $this->saved_queries[] = array('COMMIT', 0); - - @sqlite_query($this->link_id, 'COMMIT'); - } - - return @sqlite_close($this->link_id); - } - else - return false; - } - - function set_names($names) - { - return; - } - - - function get_version() - { - return array( - 'name' => 'SQLite', - 'version' => sqlite_libversion() - ); - } - - - function table_exists($table_name, $no_prefix = false) - { - $result = $this->query('SELECT 1 FROM sqlite_master WHERE name = \''.($no_prefix ? '' : $this->prefix).$this->escape($table_name).'\' AND type=\'table\''); - return $this->num_rows($result) > 0; - } - - - function field_exists($table_name, $field_name, $no_prefix = false) - { - $result = $this->query('SELECT sql FROM sqlite_master WHERE name = \''.($no_prefix ? '' : $this->prefix).$this->escape($table_name).'\' AND type=\'table\''); - if (!$this->num_rows($result)) - return false; - - return preg_match('/[\r\n]'.preg_quote($field_name).' /', $this->result($result)); - } - - - function index_exists($table_name, $index_name, $no_prefix = false) - { - $result = $this->query('SELECT 1 FROM sqlite_master WHERE tbl_name = \''.($no_prefix ? '' : $this->prefix).$this->escape($table_name).'\' AND name = \''.($no_prefix ? '' : $this->prefix).$this->escape($table_name).'_'.$this->escape($index_name).'\' AND type=\'index\''); - return $this->num_rows($result) > 0; - } - - - function create_table($table_name, $schema, $no_prefix = false) - { - if ($this->table_exists($table_name, $no_prefix)) - return true; - - $query = 'CREATE TABLE '.($no_prefix ? '' : $this->prefix).$table_name." (\n"; - - // Go through every schema element and add it to the query - foreach ($schema['FIELDS'] as $field_name => $field_data) - { - $field_data['datatype'] = preg_replace(array_keys($this->datatype_transformations), array_values($this->datatype_transformations), $field_data['datatype']); - - $query .= $field_name.' '.$field_data['datatype']; - - if (!$field_data['allow_null']) - $query .= ' NOT NULL'; - - if (isset($field_data['default'])) - $query .= ' DEFAULT '.$field_data['default']; - - $query .= ",\n"; - } - - // If we have a primary key, add it - if (isset($schema['PRIMARY KEY'])) - $query .= 'PRIMARY KEY ('.implode(',', $schema['PRIMARY KEY']).'),'."\n"; - - // Add unique keys - if (isset($schema['UNIQUE KEYS'])) - { - foreach ($schema['UNIQUE KEYS'] as $key_name => $key_fields) - $query .= 'UNIQUE ('.implode(',', $key_fields).'),'."\n"; - } - - // We remove the last two characters (a newline and a comma) and add on the ending - $query = substr($query, 0, strlen($query) - 2)."\n".')'; - - $result = $this->query($query) ? true : false; - - // Add indexes - if (isset($schema['INDEXES'])) - { - foreach ($schema['INDEXES'] as $index_name => $index_fields) - $result &= $this->add_index($table_name, $index_name, $index_fields, false, $no_prefix); - } - - return $result; - } - - - function drop_table($table_name, $no_prefix = false) - { - if (!$this->table_exists($table_name, $no_prefix)) - return true; - - return $this->query('DROP TABLE '.($no_prefix ? '' : $this->prefix).$table_name) ? true : false; - } - - - function get_table_info($table_name, $no_prefix = false) - { - // Grab table info - $result = $this->query('SELECT sql FROM sqlite_master WHERE tbl_name = \''.($no_prefix ? '' : $this->prefix).$this->escape($table_name).'\' ORDER BY type DESC') or error('Unable to fetch table information', __FILE__, __LINE__, $this->error()); - $num_rows = $this->num_rows($result); - - if ($num_rows == 0) - return; - - $table = array(); - $table['indices'] = array(); - while ($cur_index = $this->fetch_assoc($result)) - { - if (empty($cur_index['sql'])) - continue; - - if (!isset($table['sql'])) - $table['sql'] = $cur_index['sql']; - else - $table['indices'][] = $cur_index['sql']; - } - - // Work out the columns in the table currently - $table_lines = explode("\n", $table['sql']); - $table['columns'] = array(); - foreach ($table_lines as $table_line) - { - $table_line = pun_trim($table_line); - if (substr($table_line, 0, 12) == 'CREATE TABLE') - continue; - else if (substr($table_line, 0, 11) == 'PRIMARY KEY') - $table['primary_key'] = $table_line; - else if (substr($table_line, 0, 6) == 'UNIQUE') - $table['unique'] = $table_line; - else if (substr($table_line, 0, strpos($table_line, ' ')) != '') - $table['columns'][substr($table_line, 0, strpos($table_line, ' '))] = pun_trim(substr($table_line, strpos($table_line, ' '))); - } - - return $table; - } - - - function add_field($table_name, $field_name, $field_type, $allow_null, $default_value = null, $after_field = 0, $no_prefix = false) - { - if ($this->field_exists($table_name, $field_name, $no_prefix)) - return true; - - $table = $this->get_table_info($table_name, $no_prefix); - - // Create temp table - $now = time(); - $tmptable = str_replace('CREATE TABLE '.($no_prefix ? '' : $this->prefix).$this->escape($table_name).' (', 'CREATE TABLE '.($no_prefix ? '' : $this->prefix).$this->escape($table_name).'_t'.$now.' (', $table['sql']); - $result = $this->query($tmptable) ? true : false; - $result &= $this->query('INSERT INTO '.($no_prefix ? '' : $this->prefix).$this->escape($table_name).'_t'.$now.' SELECT * FROM '.($no_prefix ? '' : $this->prefix).$this->escape($table_name)) ? true : false; - - // Create new table sql - $field_type = preg_replace(array_keys($this->datatype_transformations), array_values($this->datatype_transformations), $field_type); - $query = $field_type; - if (!$allow_null) - $query .= ' NOT NULL'; - if ($default_value === null || $default_value === '') - $default_value = '\'\''; - - $query .= ' DEFAULT '.$default_value; - - $old_columns = array_keys($table['columns']); - array_insert($table['columns'], $after_field, $query.',', $field_name); - - $new_table = 'CREATE TABLE '.($no_prefix ? '' : $this->prefix).$this->escape($table_name).' ('; - - foreach ($table['columns'] as $cur_column => $column_details) - $new_table .= "\n".$cur_column.' '.$column_details; - - if (isset($table['unique'])) - $new_table .= "\n".$table['unique'].','; - - if (isset($table['primary_key'])) - $new_table .= "\n".$table['primary_key']; - - $new_table = trim($new_table, ',')."\n".');'; - - // Drop old table - $result &= $this->drop_table(($no_prefix ? '' : $this->prefix).$this->escape($table_name)); - - // Create new table - $result &= $this->query($new_table) ? true : false; - - // Recreate indexes - if (!empty($table['indices'])) - { - foreach ($table['indices'] as $cur_index) - $result &= $this->query($cur_index) ? true : false; - } - - // Copy content back - $result &= $this->query('INSERT INTO '.($no_prefix ? '' : $this->prefix).$this->escape($table_name).' ('.implode(', ', $old_columns).') SELECT * FROM '.($no_prefix ? '' : $this->prefix).$this->escape($table_name).'_t'.$now) ? true : false; - - // Drop temp table - $result &= $this->drop_table(($no_prefix ? '' : $this->prefix).$this->escape($table_name).'_t'.$now); - - return $result; - } - - - function alter_field($table_name, $field_name, $field_type, $allow_null, $default_value = null, $after_field = 0, $no_prefix = false) - { - // Unneeded for SQLite - return true; - } - - - function drop_field($table_name, $field_name, $no_prefix = false) - { - if (!$this->field_exists($table_name, $field_name, $no_prefix)) - return true; - - $table = $this->get_table_info($table_name, $no_prefix); - - // Create temp table - $now = time(); - $tmptable = str_replace('CREATE TABLE '.($no_prefix ? '' : $this->prefix).$this->escape($table_name).' (', 'CREATE TABLE '.($no_prefix ? '' : $this->prefix).$this->escape($table_name).'_t'.$now.' (', $table['sql']); - $result = $this->query($tmptable) ? true : false; - $result &= $this->query('INSERT INTO '.($no_prefix ? '' : $this->prefix).$this->escape($table_name).'_t'.$now.' SELECT * FROM '.($no_prefix ? '' : $this->prefix).$this->escape($table_name)) ? true : false; - - // Work out the columns we need to keep and the sql for the new table - unset($table['columns'][$field_name]); - $new_columns = array_keys($table['columns']); - - $new_table = 'CREATE TABLE '.($no_prefix ? '' : $this->prefix).$this->escape($table_name).' ('; - - foreach ($table['columns'] as $cur_column => $column_details) - $new_table .= "\n".$cur_column.' '.$column_details; - - if (isset($table['unique'])) - $new_table .= "\n".$table['unique'].','; - - if (isset($table['primary_key'])) - $new_table .= "\n".$table['primary_key']; - - $new_table = trim($new_table, ',')."\n".');'; - - // Drop old table - $result &= $this->drop_table(($no_prefix ? '' : $this->prefix).$this->escape($table_name)); - - // Create new table - $result &= $this->query($new_table) ? true : false; - - // Recreate indexes - if (!empty($table['indices'])) - { - foreach ($table['indices'] as $cur_index) - if (!preg_match('%\('.preg_quote($field_name, '%').'\)%', $cur_index)) - $result &= $this->query($cur_index) ? true : false; - } - - // Copy content back - $result &= $this->query('INSERT INTO '.($no_prefix ? '' : $this->prefix).$this->escape($table_name).' SELECT '.implode(', ', $new_columns).' FROM '.($no_prefix ? '' : $this->prefix).$this->escape($table_name).'_t'.$now) ? true : false; - - // Drop temp table - $result &= $this->drop_table(($no_prefix ? '' : $this->prefix).$this->escape($table_name).'_t'.$now); - - return $result; - } - - - function add_index($table_name, $index_name, $index_fields, $unique = false, $no_prefix = false) - { - if ($this->index_exists($table_name, $index_name, $no_prefix)) - return true; - - return $this->query('CREATE '.($unique ? 'UNIQUE ' : '').'INDEX '.($no_prefix ? '' : $this->prefix).$table_name.'_'.$index_name.' ON '.($no_prefix ? '' : $this->prefix).$table_name.'('.implode(',', $index_fields).')') ? true : false; - } - - - function drop_index($table_name, $index_name, $no_prefix = false) - { - if (!$this->index_exists($table_name, $index_name, $no_prefix)) - return true; - - return $this->query('DROP INDEX '.($no_prefix ? '' : $this->prefix).$table_name.'_'.$index_name) ? true : false; - } - - function truncate_table($table_name, $no_prefix = false) - { - return $this->query('DELETE FROM '.($no_prefix ? '' : $this->prefix).$table_name) ? true : false; - } -} diff --git a/upload/include/email.php b/upload/include/email.php deleted file mode 100644 index 5df0ef0..0000000 --- a/upload/include/email.php +++ /dev/null @@ -1,186 +0,0 @@ - 80) - return false; - - return preg_match('/^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|("[^"]+"))@((\[\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\])|(([a-zA-Z\d\-]+\.)+[a-zA-Z]{2,}))$/', $email); -} - - -// -// Check if $email is banned -// -function is_banned_email($email) -{ - global $db, $pun_bans; - - foreach ($pun_bans as $cur_ban) - { - if ($cur_ban['email'] != '' && - ($email == $cur_ban['email'] || - (strpos($cur_ban['email'], '@') === false && stristr($email, '@'.$cur_ban['email'])))) - return true; - } - - return false; -} - - -// -// Wrapper for PHP's mail() -// -function pun_mail($to, $subject, $message, $reply_to_email = '', $reply_to_name = '') -{ - global $pun_config, $lang_common; - - // Default sender/return address - $from_name = str_replace('"', '', $pun_config['o_board_title'].' '.$lang_common['Mailer']); - $from_email = $pun_config['o_webmaster_email']; - - // Do a little spring cleaning - $to = pun_trim(preg_replace('#[\n\r]+#s', '', $to)); - $subject = pun_trim(preg_replace('#[\n\r]+#s', '', $subject)); - $from_email = pun_trim(preg_replace('#[\n\r:]+#s', '', $from_email)); - $from_name = pun_trim(preg_replace('#[\n\r:]+#s', '', str_replace('"', '', $from_name))); - $reply_to_email = pun_trim(preg_replace('#[\n\r:]+#s', '', $reply_to_email)); - $reply_to_name = pun_trim(preg_replace('#[\n\r:]+#s', '', str_replace('"', '', $reply_to_name))); - - // Set up some headers to take advantage of UTF-8 - $from = "=?UTF-8?B?".base64_encode($from_name)."?=".' <'.$from_email.'>'; - $subject = "=?UTF-8?B?".base64_encode($subject)."?="; - - $headers = 'From: '.$from."\r\n".'Date: '.gmdate('r')."\r\n".'MIME-Version: 1.0'."\r\n".'Content-transfer-encoding: 8bit'."\r\n".'Content-type: text/plain; charset=utf-8'."\r\n".'X-Mailer: FluxBB Mailer'; - - // If we specified a reply-to email, we deal with it here - if (!empty($reply_to_email)) - { - $reply_to = "=?UTF-8?B?".base64_encode($reply_to_name)."?=".' <'.$reply_to_email.'>'; - - $headers .= "\r\n".'Reply-To: '.$reply_to; - } - - // Make sure all linebreaks are CRLF in message (and strip out any NULL bytes) - $message = str_replace(array("\n", "\0"), array("\r\n", ''), pun_linebreaks($message)); - - if ($pun_config['o_smtp_host'] != '') - smtp_mail($to, $subject, $message, $headers); - else - { - // Change the linebreaks used in the headers according to OS - if (strtoupper(substr(PHP_OS, 0, 3)) == 'MAC') - $headers = str_replace("\r\n", "\r", $headers); - else if (strtoupper(substr(PHP_OS, 0, 3)) != 'WIN') - $headers = str_replace("\r\n", "\n", $headers); - - mail($to, $subject, $message, $headers); - } -} - - -// -// This function was originally a part of the phpBB Group forum software phpBB2 (http://www.phpbb.com) -// They deserve all the credit for writing it. I made small modifications for it to suit PunBB and it's coding standards -// -function server_parse($socket, $expected_response) -{ - $server_response = ''; - while (substr($server_response, 3, 1) != ' ') - { - if (!($server_response = fgets($socket, 256))) - error('Couldn\'t get mail server response codes. Please contact the forum administrator.', __FILE__, __LINE__); - } - - if (!(substr($server_response, 0, 3) == $expected_response)) - error('Unable to send email. Please contact the forum administrator with the following error message reported by the SMTP server: "'.$server_response.'"', __FILE__, __LINE__); -} - - -// -// This function was originally a part of the phpBB Group forum software phpBB2 (http://www.phpbb.com) -// They deserve all the credit for writing it. I made small modifications for it to suit PunBB and it's coding standards. -// -function smtp_mail($to, $subject, $message, $headers = '') -{ - global $pun_config; - - $recipients = explode(',', $to); - - // Sanitize the message - $message = str_replace("\r\n.", "\r\n..", $message); - $message = (substr($message, 0, 1) == '.' ? '.'.$message : $message); - - // Are we using port 25 or a custom port? - if (strpos($pun_config['o_smtp_host'], ':') !== false) - list($smtp_host, $smtp_port) = explode(':', $pun_config['o_smtp_host']); - else - { - $smtp_host = $pun_config['o_smtp_host']; - $smtp_port = 25; - } - - if ($pun_config['o_smtp_ssl'] == '1') - $smtp_host = 'ssl://'.$smtp_host; - - if (!($socket = fsockopen($smtp_host, $smtp_port, $errno, $errstr, 15))) - error('Could not connect to smtp host "'.$pun_config['o_smtp_host'].'" ('.$errno.') ('.$errstr.')', __FILE__, __LINE__); - - server_parse($socket, '220'); - - if ($pun_config['o_smtp_user'] != '' && $pun_config['o_smtp_pass'] != '') - { - fwrite($socket, 'EHLO '.$smtp_host."\r\n"); - server_parse($socket, '250'); - - fwrite($socket, 'AUTH LOGIN'."\r\n"); - server_parse($socket, '334'); - - fwrite($socket, base64_encode($pun_config['o_smtp_user'])."\r\n"); - server_parse($socket, '334'); - - fwrite($socket, base64_encode($pun_config['o_smtp_pass'])."\r\n"); - server_parse($socket, '235'); - } - else - { - fwrite($socket, 'HELO '.$smtp_host."\r\n"); - server_parse($socket, '250'); - } - - fwrite($socket, 'MAIL FROM: <'.$pun_config['o_webmaster_email'].'>'."\r\n"); - server_parse($socket, '250'); - - foreach ($recipients as $email) - { - fwrite($socket, 'RCPT TO: <'.$email.'>'."\r\n"); - server_parse($socket, '250'); - } - - fwrite($socket, 'DATA'."\r\n"); - server_parse($socket, '354'); - - fwrite($socket, 'Subject: '.$subject."\r\n".'To: <'.implode('>, <', $recipients).'>'."\r\n".$headers."\r\n\r\n".$message."\r\n"); - - fwrite($socket, '.'."\r\n"); - server_parse($socket, '250'); - - fwrite($socket, 'QUIT'."\r\n"); - fclose($socket); - - return true; -} diff --git a/upload/include/functions.php b/upload/include/functions.php deleted file mode 100644 index d66298e..0000000 --- a/upload/include/functions.php +++ /dev/null @@ -1,1627 +0,0 @@ - 1, 'password_hash' => 'Guest'); - - // If a cookie is set, we get the user_id and password hash from it - if (isset($_COOKIE[$cookie_name])) - list($cookie['user_id'], $cookie['password_hash'], $cookie['expiration_time']) = @unserialize($_COOKIE[$cookie_name]); - - if ($cookie['user_id'] > 1) - { - // Check if there's a user with the user ID and password hash from the cookie - $result = $db->query('SELECT u.*, g.*, o.logged, o.idle FROM '.$db->prefix.'users AS u INNER JOIN '.$db->prefix.'groups AS g ON u.group_id=g.g_id LEFT JOIN '.$db->prefix.'online AS o ON o.user_id=u.id WHERE u.id='.intval($cookie['user_id'])) or error('Unable to fetch user information', __FILE__, __LINE__, $db->error()); - $pun_user = $db->fetch_assoc($result); - - // If user authorisation failed - if (!isset($pun_user['id']) || md5($cookie_seed.$pun_user['password']) !== $cookie['password_hash']) - { - $expire = $now + 31536000; // The cookie expires after a year - pun_setcookie(1, md5(uniqid(rand(), true)), $expire); - set_default_user(); - - return; - } - - // Send a new, updated cookie with a new expiration timestamp - $expire = (intval($cookie['expiration_time']) > $now + $pun_config['o_timeout_visit']) ? $now + 1209600 : $now + $pun_config['o_timeout_visit']; - pun_setcookie($pun_user['id'], $pun_user['password'], $expire); - - // Set a default language if the user selected language no longer exists - if (!file_exists(PUN_ROOT.'lang/'.$pun_user['language'])) - $pun_user['language'] = $pun_config['o_default_lang']; - - // Set a default style if the user selected style no longer exists - if (!file_exists(PUN_ROOT.'style/'.$pun_user['style'].'.css')) - $pun_user['style'] = $pun_config['o_default_style']; - - if (!$pun_user['disp_topics']) - $pun_user['disp_topics'] = $pun_config['o_disp_topics_default']; - if (!$pun_user['disp_posts']) - $pun_user['disp_posts'] = $pun_config['o_disp_posts_default']; - - // Define this if you want this visit to affect the online list and the users last visit data - if (!defined('PUN_QUIET_VISIT')) - { - // Update the online list - if (!$pun_user['logged']) - { - $pun_user['logged'] = $now; - - // With MySQL/MySQLi/SQLite, REPLACE INTO avoids a user having two rows in the online table - switch ($db_type) - { - case 'mysql': - case 'mysqli': - case 'mysql_innodb': - case 'mysqli_innodb': - case 'sqlite': - $db->query('REPLACE INTO '.$db->prefix.'online (user_id, ident, logged) VALUES('.$pun_user['id'].', \''.$db->escape($pun_user['username']).'\', '.$pun_user['logged'].')') or error('Unable to insert into online list', __FILE__, __LINE__, $db->error()); - break; - - default: - $db->query('INSERT INTO '.$db->prefix.'online (user_id, ident, logged) SELECT '.$pun_user['id'].', \''.$db->escape($pun_user['username']).'\', '.$pun_user['logged'].' WHERE NOT EXISTS (SELECT 1 FROM '.$db->prefix.'online WHERE user_id='.$pun_user['id'].')') or error('Unable to insert into online list', __FILE__, __LINE__, $db->error()); - break; - } - - // Reset tracked topics - set_tracked_topics(null); - } - else - { - // Special case: We've timed out, but no other user has browsed the forums since we timed out - if ($pun_user['logged'] < ($now-$pun_config['o_timeout_visit'])) - { - $db->query('UPDATE '.$db->prefix.'users SET last_visit='.$pun_user['logged'].' WHERE id='.$pun_user['id']) or error('Unable to update user visit data', __FILE__, __LINE__, $db->error()); - $pun_user['last_visit'] = $pun_user['logged']; - } - - $idle_sql = ($pun_user['idle'] == '1') ? ', idle=0' : ''; - $db->query('UPDATE '.$db->prefix.'online SET logged='.$now.$idle_sql.' WHERE user_id='.$pun_user['id']) or error('Unable to update online list', __FILE__, __LINE__, $db->error()); - } - } - else - { - if (!$pun_user['logged']) - $pun_user['logged'] = $pun_user['last_visit']; - } - - $pun_user['is_guest'] = false; - $pun_user['is_admmod'] = $pun_user['g_id'] == PUN_ADMIN || $pun_user['g_moderator'] == '1'; - } - else - set_default_user(); -} - - -// -// Converts the CDATA end sequence ]]> into ]]> -// -function escape_cdata($str) -{ - return str_replace(']]>', ']]>', $str); -} - - -// -// Authenticates the provided username and password against the user database -// $user can be either a user ID (integer) or a username (string) -// $password can be either a plaintext password or a password hash including salt ($password_is_hash must be set accordingly) -// -function authenticate_user($user, $password, $password_is_hash = false) -{ - global $db, $pun_user; - - // Check if there's a user matching $user and $password - $result = $db->query('SELECT u.*, g.*, o.logged, o.idle FROM '.$db->prefix.'users AS u INNER JOIN '.$db->prefix.'groups AS g ON g.g_id=u.group_id LEFT JOIN '.$db->prefix.'online AS o ON o.user_id=u.id WHERE '.(is_int($user) ? 'u.id='.intval($user) : 'u.username=\''.$db->escape($user).'\'')) or error('Unable to fetch user info', __FILE__, __LINE__, $db->error()); - $pun_user = $db->fetch_assoc($result); - - if (!isset($pun_user['id']) || - ($password_is_hash && $password != $pun_user['password']) || - (!$password_is_hash && pun_hash($password) != $pun_user['password'])) - set_default_user(); - else - $pun_user['is_guest'] = false; -} - - -// -// Try to determine the current URL -// -function get_current_url($max_length = 0) -{ - $protocol = (!isset($_SERVER['HTTPS']) || strtolower($_SERVER['HTTPS']) == 'off') ? 'http://' : 'https://'; - $port = (isset($_SERVER['SERVER_PORT']) && (($_SERVER['SERVER_PORT'] != '80' && $protocol == 'http://') || ($_SERVER['SERVER_PORT'] != '443' && $protocol == 'https://')) && strpos($_SERVER['HTTP_HOST'], ':') === false) ? ':'.$_SERVER['SERVER_PORT'] : ''; - - $url = urldecode($protocol.$_SERVER['HTTP_HOST'].$port.$_SERVER['REQUEST_URI']); - - if (strlen($url) <= $max_length || $max_length == 0) - return $url; - - // We can't find a short enough url - return null; -} - - -// -// Fill $pun_user with default values (for guests) -// -function set_default_user() -{ - global $db, $db_type, $pun_user, $pun_config; - - $remote_addr = get_remote_address(); - - // Fetch guest user - $result = $db->query('SELECT u.*, g.*, o.logged, o.last_post, o.last_search FROM '.$db->prefix.'users AS u INNER JOIN '.$db->prefix.'groups AS g ON u.group_id=g.g_id LEFT JOIN '.$db->prefix.'online AS o ON o.ident=\''.$remote_addr.'\' WHERE u.id=1') or error('Unable to fetch guest information', __FILE__, __LINE__, $db->error()); - if (!$db->num_rows($result)) - exit('Unable to fetch guest information. The table \''.$db->prefix.'users\' must contain an entry with id = 1 that represents anonymous users.'); - - $pun_user = $db->fetch_assoc($result); - - // Update online list - if (!$pun_user['logged']) - { - $pun_user['logged'] = time(); - - // With MySQL/MySQLi/SQLite, REPLACE INTO avoids a user having two rows in the online table - switch ($db_type) - { - case 'mysql': - case 'mysqli': - case 'mysql_innodb': - case 'mysqli_innodb': - case 'sqlite': - $db->query('REPLACE INTO '.$db->prefix.'online (user_id, ident, logged) VALUES(1, \''.$db->escape($remote_addr).'\', '.$pun_user['logged'].')') or error('Unable to insert into online list', __FILE__, __LINE__, $db->error()); - break; - - default: - $db->query('INSERT INTO '.$db->prefix.'online (user_id, ident, logged) SELECT 1, \''.$db->escape($remote_addr).'\', '.$pun_user['logged'].' WHERE NOT EXISTS (SELECT 1 FROM '.$db->prefix.'online WHERE ident=\''.$db->escape($remote_addr).'\')') or error('Unable to insert into online list', __FILE__, __LINE__, $db->error()); - break; - } - } - else - $db->query('UPDATE '.$db->prefix.'online SET logged='.time().' WHERE ident=\''.$db->escape($remote_addr).'\'') or error('Unable to update online list', __FILE__, __LINE__, $db->error()); - - $pun_user['disp_topics'] = $pun_config['o_disp_topics_default']; - $pun_user['disp_posts'] = $pun_config['o_disp_posts_default']; - $pun_user['timezone'] = $pun_config['o_default_timezone']; - $pun_user['dst'] = $pun_config['o_default_dst']; - $pun_user['language'] = $pun_config['o_default_lang']; - $pun_user['style'] = $pun_config['o_default_style']; - $pun_user['is_guest'] = true; - $pun_user['is_admmod'] = false; -} - - -// -// Set a cookie, FluxBB style! -// Wrapper for forum_setcookie -// -function pun_setcookie($user_id, $password_hash, $expire) -{ - global $cookie_name, $cookie_seed; - - forum_setcookie($cookie_name, serialize(array($user_id, md5($cookie_seed.$password_hash), $expire)), $expire); -} - - -// -// Set a cookie, FluxBB style! -// -function forum_setcookie($name, $value, $expire) -{ - global $cookie_path, $cookie_domain, $cookie_secure; - - // Enable sending of a P3P header - header('P3P: CP="CUR ADM"'); - - if (version_compare(PHP_VERSION, '5.2.0', '>=')) - setcookie($name, $value, $expire, $cookie_path, $cookie_domain, $cookie_secure, true); - else - setcookie($name, $value, $expire, $cookie_path.'; HttpOnly', $cookie_domain, $cookie_secure); -} - - -// -// Check whether the connecting user is banned (and delete any expired bans while we're at it) -// -function check_bans() -{ - global $db, $pun_config, $lang_common, $pun_user, $pun_bans; - - // Admins aren't affected - if ($pun_user['g_id'] == PUN_ADMIN || !$pun_bans) - return; - - // Add a dot or a colon (depending on IPv4/IPv6) at the end of the IP address to prevent banned address - // 192.168.0.5 from matching e.g. 192.168.0.50 - $user_ip = get_remote_address(); - $user_ip .= (strpos($user_ip, '.') !== false) ? '.' : ':'; - - $bans_altered = false; - $is_banned = false; - - foreach ($pun_bans as $cur_ban) - { - // Has this ban expired? - if ($cur_ban['expire'] != '' && $cur_ban['expire'] <= time()) - { - $db->query('DELETE FROM '.$db->prefix.'bans WHERE id='.$cur_ban['id']) or error('Unable to delete expired ban', __FILE__, __LINE__, $db->error()); - $bans_altered = true; - continue; - } - - if ($cur_ban['username'] != '' && utf8_strtolower($pun_user['username']) == utf8_strtolower($cur_ban['username'])) - $is_banned = true; - - if ($cur_ban['ip'] != '') - { - $cur_ban_ips = explode(' ', $cur_ban['ip']); - - $num_ips = count($cur_ban_ips); - for ($i = 0; $i < $num_ips; ++$i) - { - // Add the proper ending to the ban - if (strpos($user_ip, '.') !== false) - $cur_ban_ips[$i] = $cur_ban_ips[$i].'.'; - else - $cur_ban_ips[$i] = $cur_ban_ips[$i].':'; - - if (substr($user_ip, 0, strlen($cur_ban_ips[$i])) == $cur_ban_ips[$i]) - { - $is_banned = true; - break; - } - } - } - - if ($is_banned) - { - $db->query('DELETE FROM '.$db->prefix.'online WHERE ident=\''.$db->escape($pun_user['username']).'\'') or error('Unable to delete from online list', __FILE__, __LINE__, $db->error()); - message($lang_common['Ban message'].' '.(($cur_ban['expire'] != '') ? $lang_common['Ban message 2'].' '.strtolower(format_time($cur_ban['expire'], true)).'. ' : '').(($cur_ban['message'] != '') ? $lang_common['Ban message 3'].'

    '.pun_htmlspecialchars($cur_ban['message']).'

    ' : '

    ').$lang_common['Ban message 4'].' '.$pun_config['o_admin_email'].'.', true); - } - } - - // If we removed any expired bans during our run-through, we need to regenerate the bans cache - if ($bans_altered) - { - if (!defined('FORUM_CACHE_FUNCTIONS_LOADED')) - require PUN_ROOT.'include/cache.php'; - - generate_bans_cache(); - } -} - - -// -// Check username -// -function check_username($username, $exclude_id = null) -{ - global $db, $pun_config, $errors, $lang_prof_reg, $lang_register, $lang_common, $pun_bans; - - // Convert multiple whitespace characters into one (to prevent people from registering with indistinguishable usernames) - $username = preg_replace('#\s+#s', ' ', $username); - - // Validate username - if (pun_strlen($username) < 2) - $errors[] = $lang_prof_reg['Username too short']; - else if (pun_strlen($username) > 25) // This usually doesn't happen since the form element only accepts 25 characters - $errors[] = $lang_prof_reg['Username too long']; - else if (!strcasecmp($username, 'Guest') || !strcasecmp($username, $lang_common['Guest'])) - $errors[] = $lang_prof_reg['Username guest']; - else if (preg_match('/[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}/', $username) || preg_match('/((([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}:[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){5}:([0-9A-Fa-f]{1,4}:)?[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){4}:([0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){3}:([0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){2}:([0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|(([0-9A-Fa-f]{1,4}:){0,5}:((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|(::([0-9A-Fa-f]{1,4}:){0,5}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|([0-9A-Fa-f]{1,4}::([0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})|(::([0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){1,7}:))/', $username)) - $errors[] = $lang_prof_reg['Username IP']; - else if ((strpos($username, '[') !== false || strpos($username, ']') !== false) && strpos($username, '\'') !== false && strpos($username, '"') !== false) - $errors[] = $lang_prof_reg['Username reserved chars']; - else if (preg_match('/(?:\[\/?(?:b|u|i|h|colou?r|quote|code|img|url|email|list|\*)\]|\[(?:img|url|quote|list)=)/i', $username)) - $errors[] = $lang_prof_reg['Username BBCode']; - - // Check username for any censored words - if ($pun_config['o_censoring'] == '1' && censor_words($username) != $username) - $errors[] = $lang_register['Username censor']; - - // Check that the username (or a too similar username) is not already registered - $query = ($exclude_id) ? ' AND id!='.$exclude_id : ''; - - $result = $db->query('SELECT username FROM '.$db->prefix.'users WHERE (UPPER(username)=UPPER(\''.$db->escape($username).'\') OR UPPER(username)=UPPER(\''.$db->escape(preg_replace('/[^\w]/', '', $username)).'\')) AND id>1'.$query) or error('Unable to fetch user info', __FILE__, __LINE__, $db->error()); - - if ($db->num_rows($result)) - { - $busy = $db->result($result); - $errors[] = $lang_register['Username dupe 1'].' '.pun_htmlspecialchars($busy).'. '.$lang_register['Username dupe 2']; - } - - // Check username for any banned usernames - foreach ($pun_bans as $cur_ban) - { - if ($cur_ban['username'] != '' && utf8_strtolower($username) == utf8_strtolower($cur_ban['username'])) - { - $errors[] = $lang_prof_reg['Banned username']; - break; - } - } -} - - -// -// Update "Users online" -// -function update_users_online() -{ - global $db, $pun_config; - - $now = time(); - - // Fetch all online list entries that are older than "o_timeout_online" - $result = $db->query('SELECT user_id, ident, logged, idle FROM '.$db->prefix.'online WHERE logged<'.($now-$pun_config['o_timeout_online'])) or error('Unable to fetch old entries from online list', __FILE__, __LINE__, $db->error()); - while ($cur_user = $db->fetch_assoc($result)) - { - // If the entry is a guest, delete it - if ($cur_user['user_id'] == '1') - $db->query('DELETE FROM '.$db->prefix.'online WHERE ident=\''.$db->escape($cur_user['ident']).'\'') or error('Unable to delete from online list', __FILE__, __LINE__, $db->error()); - else - { - // If the entry is older than "o_timeout_visit", update last_visit for the user in question, then delete him/her from the online list - if ($cur_user['logged'] < ($now-$pun_config['o_timeout_visit'])) - { - $db->query('UPDATE '.$db->prefix.'users SET last_visit='.$cur_user['logged'].' WHERE id='.$cur_user['user_id']) or error('Unable to update user visit data', __FILE__, __LINE__, $db->error()); - $db->query('DELETE FROM '.$db->prefix.'online WHERE user_id='.$cur_user['user_id']) or error('Unable to delete from online list', __FILE__, __LINE__, $db->error()); - } - else if ($cur_user['idle'] == '0') - $db->query('UPDATE '.$db->prefix.'online SET idle=1 WHERE user_id='.$cur_user['user_id']) or error('Unable to insert into online list', __FILE__, __LINE__, $db->error()); - } - } -} - - -// -// Generate the "navigator" that appears at the top of every page -// -function generate_navlinks() -{ - global $pun_config, $lang_common, $pun_user; - - // Index and Userlist should always be displayed - $links[] = ''; - - if ($pun_user['g_read_board'] == '1' && $pun_user['g_view_users'] == '1') - $links[] = ''; - - if ($pun_config['o_rules'] == '1' && (!$pun_user['is_guest'] || $pun_user['g_read_board'] == '1' || $pun_config['o_regs_allow'] == '1')) - $links[] = ''; - - if ($pun_user['is_guest']) - { - if ($pun_user['g_read_board'] == '1' && $pun_user['g_search'] == '1') - $links[] = ''; - - $links[] = ''; - $links[] = ''; - - $info = $lang_common['Not logged in']; - } - else - { - if (!$pun_user['is_admmod']) - { - if ($pun_user['g_read_board'] == '1' && $pun_user['g_search'] == '1') - $links[] = ''; - - $links[] = ''; - $links[] = ''; - } - else - { - $links[] = ''; - $links[] = ''; - $links[] = ''; - $links[] = ''; - } - } - - // Are there any additional navlinks we should insert into the array before imploding it? - if ($pun_config['o_additional_navlinks'] != '') - { - if (preg_match_all('#([0-9]+)\s*=\s*(.*?)\n#s', $pun_config['o_additional_navlinks']."\n", $extra_links)) - { - // Insert any additional links into the $links array (at the correct index) - $num_links = count($extra_links[1]); - for ($i = 0; $i < $num_links; ++$i) - array_splice($links, $extra_links[1][$i], 0, array('')); - } - } - - return '
      '."\n\t\t\t\t".implode("\n\t\t\t\t", $links)."\n\t\t\t".'
    '; -} - - -// -// Display the profile navigation menu -// -function generate_profile_menu($page = '') -{ - global $lang_profile, $pun_config, $pun_user, $id; - -?> -
    -
    -

    -
    -
    -
      - > - > - > - > - > - > - > -
    -
    -
    -
    -'; - break; - } - } - - return $avatar_markup; -} - - -// -// Generate browser's title -// -function generate_page_title($page_title, $p = null) -{ - global $pun_config, $lang_common; - - $page_title = array_reverse($page_title); - - if ($p != null) - $page_title[0] .= ' ('.sprintf($lang_common['Page'], forum_number_format($p)).')'; - - $crumbs = implode($lang_common['Title separator'], $page_title); - - return $crumbs; -} - - -// -// Save array of tracked topics in cookie -// -function set_tracked_topics($tracked_topics) -{ - global $cookie_name, $cookie_path, $cookie_domain, $cookie_secure, $pun_config; - - $cookie_data = ''; - if (!empty($tracked_topics)) - { - // Sort the arrays (latest read first) - arsort($tracked_topics['topics'], SORT_NUMERIC); - arsort($tracked_topics['forums'], SORT_NUMERIC); - - // Homebrew serialization (to avoid having to run unserialize() on cookie data) - foreach ($tracked_topics['topics'] as $id => $timestamp) - $cookie_data .= 't'.$id.'='.$timestamp.';'; - foreach ($tracked_topics['forums'] as $id => $timestamp) - $cookie_data .= 'f'.$id.'='.$timestamp.';'; - - // Enforce a 4048 byte size limit (4096 minus some space for the cookie name) - if (strlen($cookie_data) > 4048) - { - $cookie_data = substr($cookie_data, 0, 4048); - $cookie_data = substr($cookie_data, 0, strrpos($cookie_data, ';')).';'; - } - } - - forum_setcookie($cookie_name.'_track', $cookie_data, time() + $pun_config['o_timeout_visit']); - $_COOKIE[$cookie_name.'_track'] = $cookie_data; // Set it directly in $_COOKIE as well -} - - -// -// Extract array of tracked topics from cookie -// -function get_tracked_topics() -{ - global $cookie_name; - - $cookie_data = isset($_COOKIE[$cookie_name.'_track']) ? $_COOKIE[$cookie_name.'_track'] : false; - if (!$cookie_data) - return array('topics' => array(), 'forums' => array()); - - if (strlen($cookie_data) > 4048) - return array('topics' => array(), 'forums' => array()); - - // Unserialize data from cookie - $tracked_topics = array('topics' => array(), 'forums' => array()); - $temp = explode(';', $cookie_data); - foreach ($temp as $t) - { - $type = substr($t, 0, 1) == 'f' ? 'forums' : 'topics'; - $id = intval(substr($t, 1)); - $timestamp = intval(substr($t, strpos($t, '=') + 1)); - if ($id > 0 && $timestamp > 0) - $tracked_topics[$type][$id] = $timestamp; - } - - return $tracked_topics; -} - - -// -// Update posts, topics, last_post, last_post_id and last_poster for a forum -// -function update_forum($forum_id) -{ - global $db; - - $result = $db->query('SELECT COUNT(id), SUM(num_replies) FROM '.$db->prefix.'topics WHERE forum_id='.$forum_id) or error('Unable to fetch forum topic count', __FILE__, __LINE__, $db->error()); - list($num_topics, $num_posts) = $db->fetch_row($result); - - $num_posts = $num_posts + $num_topics; // $num_posts is only the sum of all replies (we have to add the topic posts) - - $result = $db->query('SELECT last_post, last_post_id, last_poster FROM '.$db->prefix.'topics WHERE forum_id='.$forum_id.' AND moved_to IS NULL ORDER BY last_post DESC LIMIT 1') or error('Unable to fetch last_post/last_post_id/last_poster', __FILE__, __LINE__, $db->error()); - if ($db->num_rows($result)) // There are topics in the forum - { - list($last_post, $last_post_id, $last_poster) = $db->fetch_row($result); - - $db->query('UPDATE '.$db->prefix.'forums SET num_topics='.$num_topics.', num_posts='.$num_posts.', last_post='.$last_post.', last_post_id='.$last_post_id.', last_poster=\''.$db->escape($last_poster).'\' WHERE id='.$forum_id) or error('Unable to update last_post/last_post_id/last_poster', __FILE__, __LINE__, $db->error()); - } - else // There are no topics - $db->query('UPDATE '.$db->prefix.'forums SET num_topics='.$num_topics.', num_posts='.$num_posts.', last_post=NULL, last_post_id=NULL, last_poster=NULL WHERE id='.$forum_id) or error('Unable to update last_post/last_post_id/last_poster', __FILE__, __LINE__, $db->error()); -} - - -// -// Deletes any avatars owned by the specified user ID -// -function delete_avatar($user_id) -{ - global $pun_config; - - $filetypes = array('jpg', 'gif', 'png'); - - // Delete user avatar - foreach ($filetypes as $cur_type) - { - if (file_exists(PUN_ROOT.$pun_config['o_avatars_dir'].'/'.$user_id.'.'.$cur_type)) - @unlink(PUN_ROOT.$pun_config['o_avatars_dir'].'/'.$user_id.'.'.$cur_type); - } -} - - -// -// Delete a topic and all of it's posts -// -function delete_topic($topic_id) -{ - global $db; - - // Delete the topic and any redirect topics - $db->query('DELETE FROM '.$db->prefix.'topics WHERE id='.$topic_id.' OR moved_to='.$topic_id) or error('Unable to delete topic', __FILE__, __LINE__, $db->error()); - - // Create a list of the post IDs in this topic - $post_ids = ''; - $result = $db->query('SELECT id FROM '.$db->prefix.'posts WHERE topic_id='.$topic_id) or error('Unable to fetch posts', __FILE__, __LINE__, $db->error()); - while ($row = $db->fetch_row($result)) - $post_ids .= ($post_ids != '') ? ','.$row[0] : $row[0]; - - // Make sure we have a list of post IDs - if ($post_ids != '') - { - strip_search_index($post_ids); - - // Delete posts in topic - $db->query('DELETE FROM '.$db->prefix.'posts WHERE topic_id='.$topic_id) or error('Unable to delete posts', __FILE__, __LINE__, $db->error()); - } - - // Delete any subscriptions for this topic - $db->query('DELETE FROM '.$db->prefix.'subscriptions WHERE topic_id='.$topic_id) or error('Unable to delete subscriptions', __FILE__, __LINE__, $db->error()); -} - - -// -// Delete a single post -// -function delete_post($post_id, $topic_id) -{ - global $db; - - $result = $db->query('SELECT id, poster, posted FROM '.$db->prefix.'posts WHERE topic_id='.$topic_id.' ORDER BY id DESC LIMIT 2') or error('Unable to fetch post info', __FILE__, __LINE__, $db->error()); - list($last_id, ,) = $db->fetch_row($result); - list($second_last_id, $second_poster, $second_posted) = $db->fetch_row($result); - - // Delete the post - $db->query('DELETE FROM '.$db->prefix.'posts WHERE id='.$post_id) or error('Unable to delete post', __FILE__, __LINE__, $db->error()); - - strip_search_index($post_id); - - // Count number of replies in the topic - $result = $db->query('SELECT COUNT(id) FROM '.$db->prefix.'posts WHERE topic_id='.$topic_id) or error('Unable to fetch post count for topic', __FILE__, __LINE__, $db->error()); - $num_replies = $db->result($result, 0) - 1; - - // If the message we deleted is the most recent in the topic (at the end of the topic) - if ($last_id == $post_id) - { - // If there is a $second_last_id there is more than 1 reply to the topic - if (!empty($second_last_id)) - $db->query('UPDATE '.$db->prefix.'topics SET last_post='.$second_posted.', last_post_id='.$second_last_id.', last_poster=\''.$db->escape($second_poster).'\', num_replies='.$num_replies.' WHERE id='.$topic_id) or error('Unable to update topic', __FILE__, __LINE__, $db->error()); - else - // We deleted the only reply, so now last_post/last_post_id/last_poster is posted/id/poster from the topic itself - $db->query('UPDATE '.$db->prefix.'topics SET last_post=posted, last_post_id=id, last_poster=poster, num_replies='.$num_replies.' WHERE id='.$topic_id) or error('Unable to update topic', __FILE__, __LINE__, $db->error()); - } - else - // Otherwise we just decrement the reply counter - $db->query('UPDATE '.$db->prefix.'topics SET num_replies='.$num_replies.' WHERE id='.$topic_id) or error('Unable to update topic', __FILE__, __LINE__, $db->error()); -} - - -// -// Delete every .php file in the forum's cache directory -// -function forum_clear_cache() -{ - $d = dir(FORUM_CACHE_DIR); - while (($entry = $d->read()) !== false) - { - if (substr($entry, strlen($entry)-4) == '.php') - @unlink(FORUM_CACHE_DIR.$entry); - } - $d->close(); -} - - -// -// Replace censored words in $text -// -function censor_words($text) -{ - global $db; - static $search_for, $replace_with; - - // If not already built in a previous call, build an array of censor words and their replacement text - if (!isset($search_for)) - { - $result = $db->query('SELECT search_for, replace_with FROM '.$db->prefix.'censoring') or error('Unable to fetch censor word list', __FILE__, __LINE__, $db->error()); - $num_words = $db->num_rows($result); - - $search_for = array(); - for ($i = 0; $i < $num_words; ++$i) - { - list($search_for[$i], $replace_with[$i]) = $db->fetch_row($result); - $search_for[$i] = '/\b('.str_replace('\*', '\w*?', preg_quote($search_for[$i], '/')).')\b/i'; - } - } - - if (!empty($search_for)) - $text = substr(preg_replace($search_for, $replace_with, ' '.$text.' '), 1, -1); - - return $text; -} - - -// -// Determines the correct title for $user -// $user must contain the elements 'username', 'title', 'posts', 'g_id' and 'g_user_title' -// -function get_title($user) -{ - global $db, $pun_config, $pun_bans, $lang_common; - static $ban_list, $pun_ranks; - - // If not already built in a previous call, build an array of lowercase banned usernames - if (empty($ban_list)) - { - $ban_list = array(); - - foreach ($pun_bans as $cur_ban) - $ban_list[] = strtolower($cur_ban['username']); - } - - // If not already loaded in a previous call, load the cached ranks - if ($pun_config['o_ranks'] == '1' && empty($pun_ranks)) - { - if (file_exists(FORUM_CACHE_DIR.'cache_ranks.php')) - include FORUM_CACHE_DIR.'cache_ranks.php'; - - if (!defined('PUN_RANKS_LOADED')) - { - if (!defined('FORUM_CACHE_FUNCTIONS_LOADED')) - require PUN_ROOT.'include/cache.php'; - - generate_ranks_cache(); - require FORUM_CACHE_DIR.'cache_ranks.php'; - } - } - - // If the user has a custom title - if ($user['title'] != '') - $user_title = pun_htmlspecialchars($user['title']); - // If the user is banned - else if (in_array(strtolower($user['username']), $ban_list)) - $user_title = $lang_common['Banned']; - // If the user group has a default user title - else if ($user['g_user_title'] != '') - $user_title = pun_htmlspecialchars($user['g_user_title']); - // If the user is a guest - else if ($user['g_id'] == PUN_GUEST) - $user_title = $lang_common['Guest']; - else - { - // Are there any ranks? - if ($pun_config['o_ranks'] == '1' && !empty($pun_ranks)) - { - foreach ($pun_ranks as $cur_rank) - { - if (intval($user['num_posts']) >= $cur_rank['min_posts']) - $user_title = pun_htmlspecialchars($cur_rank['rank']); - } - } - - // If the user didn't "reach" any rank (or if ranks are disabled), we assign the default - if (!isset($user_title)) - $user_title = $lang_common['Member']; - } - - return $user_title; -} - - -// -// Generate a string with numbered links (for multipage scripts) -// -function paginate($num_pages, $cur_page, $link) -{ - global $lang_common; - - $pages = array(); - $link_to_all = false; - - // If $cur_page == -1, we link to all pages (used in viewforum.php) - if ($cur_page == -1) - { - $cur_page = 1; - $link_to_all = true; - } - - if ($num_pages <= 1) - $pages = array('1'); - else - { - // Add a previous page link - if ($num_pages > 1 && $cur_page > 1) - $pages[] = ''.$lang_common['Previous'].''; - - if ($cur_page > 3) - { - $pages[] = '1'; - - if ($cur_page > 5) - $pages[] = ''.$lang_common['Spacer'].''; - } - - // Don't ask me how the following works. It just does, OK? :-) - for ($current = ($cur_page == 5) ? $cur_page - 3 : $cur_page - 2, $stop = ($cur_page + 4 == $num_pages) ? $cur_page + 4 : $cur_page + 3; $current < $stop; ++$current) - { - if ($current < 1 || $current > $num_pages) - continue; - else if ($current != $cur_page || $link_to_all) - $pages[] = ''.forum_number_format($current).''; - else - $pages[] = ''.forum_number_format($current).'
    '; - } - - if ($cur_page <= ($num_pages-3)) - { - if ($cur_page != ($num_pages-3) && $cur_page != ($num_pages-4)) - $pages[] = ''.$lang_common['Spacer'].''; - - $pages[] = ''.forum_number_format($num_pages).''; - } - - // Add a next page link - if ($num_pages > 1 && !$link_to_all && $cur_page < $num_pages) - $pages[] = ''.$lang_common['Next'].''; - } - - return implode(' ', $pages); -} - - -// -// Display a message -// -function message($message, $no_back_link = false) -{ - global $db, $lang_common, $pun_config, $pun_start, $tpl_main; - - if (!defined('PUN_HEADER')) - { - global $pun_user; - - $page_title = array(pun_htmlspecialchars($pun_config['o_board_title']), $lang_common['Info']); - define('PUN_ACTIVE_PAGE', 'index'); - require PUN_ROOT.'header.php'; - } - -?> - -
    -

    -
    -
    -

    -

    -
    -
    -
    - count($input)) - $offset = count($input); - else if ($offset < 0) - $offset = 0; - - $input = array_merge(array_slice($input, 0, $offset), array($key => $element), array_slice($input, $offset)); -} - - -// -// Display a message when board is in maintenance mode -// -function maintenance_message() -{ - global $db, $pun_config, $lang_common, $pun_user; - - // Deal with newlines, tabs and multiple spaces - $pattern = array("\t", ' ', ' '); - $replace = array('    ', '  ', '  '); - $message = str_replace($pattern, $replace, $pun_config['o_maintenance_message']); - - - if (file_exists(PUN_ROOT.'style/'.$pun_user['style'].'/maintenance.tpl')) - { - $tpl_file = PUN_ROOT.'style/'.$pun_user['style'].'/maintenance.tpl'; - $tpl_inc_dir = PUN_ROOT.'style/'.$pun_user['style'].'/'; - } - else - { - $tpl_file = PUN_ROOT.'include/template/maintenance.tpl'; - $tpl_inc_dir = PUN_ROOT.'include/user/'; - } - - $tpl_maint = file_get_contents($tpl_file); - - // START SUBST - - preg_match_all('##', $tpl_maint, $pun_includes, PREG_SET_ORDER); - - foreach ($pun_includes as $cur_include) - { - if (!file_exists($tpl_inc_dir.$cur_include[1].'.'.$cur_include[2])) - error(sprintf($lang_common['Pun include error'], htmlspecialchars($cur_include[0]), basename($tpl_file), $tpl_inc_dir)); - - ob_start(); - - require $tpl_inc_dir.$cur_include[1].'.'.$cur_include[2]; - - $tpl_temp = ob_get_contents(); - $tpl_maint = str_replace($cur_include[0], $tpl_temp, $tpl_maint); - ob_end_clean(); - } - // END SUBST - - - - // START SUBST - - $tpl_maint = str_replace('', $lang_common['lang_identifier'], $tpl_maint); - // END SUBST - - - - // START SUBST - - $tpl_maint = str_replace('', $lang_common['lang_direction'], $tpl_maint); - // END SUBST - - - - // START SUBST - - ob_start(); - - $page_title = array(pun_htmlspecialchars($pun_config['o_board_title']), $lang_common['Maintenance']); - -?> -<?php echo generate_page_title($page_title) ?> - -', $tpl_temp, $tpl_maint); - ob_end_clean(); - // END SUBST - - - - // START SUBST - - ob_start(); - -?> -
    -

    -
    -
    -

    -
    -
    -
    -', $tpl_temp, $tpl_main); - ob_end_clean(); - // END SUBST - - - - // End the transaction - $db->end_transaction(); - - - // Close the db connection (and free up any result data) - $db->close(); - - exit($tpl_maint); -} - - -// -// Display $message and redirect user to $destination_url -// -function redirect($destination_url, $message) -{ - global $db, $pun_config, $lang_common, $pun_user; - - // Prefix with o_base_url (unless there's already a valid URI) - if (strpos($destination_url, 'http://') !== 0 && strpos($destination_url, 'https://') !== 0 && strpos($destination_url, '/') !== 0) - $destination_url = $pun_config['o_base_url'].'/'.$destination_url; - - // Do a little spring cleaning - $destination_url = preg_replace('/([\r\n])|(%0[ad])|(;\s*data\s*:)/i', '', $destination_url); - - // If the delay is 0 seconds, we might as well skip the redirect all together - if ($pun_config['o_redirect_delay'] == '0') - header('Location: '.str_replace('&', '&', $destination_url)); - - - if (file_exists(PUN_ROOT.'style/'.$pun_user['style'].'/redirect.tpl')) - { - $tpl_file = PUN_ROOT.'style/'.$pun_user['style'].'/redirect.tpl'; - $tpl_inc_dir = PUN_ROOT.'style/'.$pun_user['style'].'/'; - } - else - { - $tpl_file = PUN_ROOT.'include/template/redirect.tpl'; - $tpl_inc_dir = PUN_ROOT.'include/user/'; - } - - $tpl_redir = file_get_contents($tpl_file); - - // START SUBST - - preg_match_all('##', $tpl_redir, $pun_includes, PREG_SET_ORDER); - - foreach ($pun_includes as $cur_include) - { - if (!file_exists($tpl_inc_dir.$cur_include[1].'.'.$cur_include[2])) - error(sprintf($lang_common['Pun include error'], htmlspecialchars($cur_include[0]), basename($tpl_file), $tpl_inc_dir)); - - ob_start(); - - require $tpl_inc_dir.$cur_include[1].'.'.$cur_include[2]; - - $tpl_temp = ob_get_contents(); - $tpl_redir = str_replace($cur_include[0], $tpl_temp, $tpl_redir); - ob_end_clean(); - } - // END SUBST - - - - // START SUBST - - $tpl_redir = str_replace('', $lang_common['lang_identifier'], $tpl_redir); - // END SUBST - - - - // START SUBST - - $tpl_redir = str_replace('', $lang_common['lang_direction'], $tpl_redir); - // END SUBST - - - - // START SUBST - - ob_start(); - - $page_title = array(pun_htmlspecialchars($pun_config['o_board_title']), $lang_common['Redirecting']); - -?> -" /> -<?php echo generate_page_title($page_title) ?> - -', $tpl_temp, $tpl_redir); - ob_end_clean(); - // END SUBST - - - - // START SUBST - - ob_start(); - -?> - -', $tpl_temp, $tpl_redir); - ob_end_clean(); - // END SUBST - - - - // START SUBST - - ob_start(); - - // End the transaction - $db->end_transaction(); - - // Display executed queries (if enabled) - if (defined('PUN_SHOW_QUERIES')) - display_saved_queries(); - - $tpl_temp = trim(ob_get_contents()); - $tpl_redir = str_replace('', $tpl_temp, $tpl_redir); - ob_end_clean(); - // END SUBST - - - - // Close the db connection (and free up any result data) - $db->close(); - - exit($tpl_redir); -} - - -// -// Display a simple error message -// -function error($message, $file = null, $line = null, $db_error = false) -{ - global $pun_config, $lang_common; - - // Set some default settings if the script failed before $pun_config could be populated - if (empty($pun_config)) - { - $pun_config = array( - 'o_board_title' => 'FluxBB', - 'o_gzip' => '0' - ); - } - - // Set some default translations if the script failed before $lang_common could be populated - if (empty($lang_common)) - { - $lang_common = array( - 'Title separator' => ' / ', - 'Page' => 'Page %s' - ); - } - - // Empty all output buffers and stop buffering - while (@ob_end_clean()); - - // "Restart" output buffering if we are using ob_gzhandler (since the gzip header is already sent) - if ($pun_config['o_gzip'] && extension_loaded('zlib')) - ob_start('ob_gzhandler'); - -?> - - - - - -<?php echo generate_page_title($page_title) ?> - - - - -
    -

    An error was encountered

    -
    -File: '.$file.'
    '."\n\t\t".'Line: '.$line.'

    '."\n\t\t".'FluxBB reported: '.$message."\n"; - - if ($db_error) - { - echo "\t\t".'

    Database reported: '.pun_htmlspecialchars($db_error['error_msg']).(($db_error['error_no']) ? ' (Errno: '.$db_error['error_no'].')' : '')."\n"; - - if ($db_error['error_sql'] != '') - echo "\t\t".'

    Failed query: '.pun_htmlspecialchars($db_error['error_sql'])."\n"; - } - } - else - echo "\t\t".'Error: '.$message.'.'."\n"; - -?> -
    -
    - - - -close(); - - exit; -} - - -// -// Unset any variables instantiated as a result of register_globals being enabled -// -function forum_unregister_globals() -{ - $register_globals = ini_get('register_globals'); - if ($register_globals === "" || $register_globals === "0" || strtolower($register_globals) === "off") - return; - - // Prevent script.php?GLOBALS[foo]=bar - if (isset($_REQUEST['GLOBALS']) || isset($_FILES['GLOBALS'])) - exit('I\'ll have a steak sandwich and... a steak sandwich.'); - - // Variables that shouldn't be unset - $no_unset = array('GLOBALS', '_GET', '_POST', '_COOKIE', '_REQUEST', '_SERVER', '_ENV', '_FILES'); - - // Remove elements in $GLOBALS that are present in any of the superglobals - $input = array_merge($_GET, $_POST, $_COOKIE, $_SERVER, $_ENV, $_FILES, isset($_SESSION) && is_array($_SESSION) ? $_SESSION : array()); - foreach ($input as $k => $v) - { - if (!in_array($k, $no_unset) && isset($GLOBALS[$k])) - { - unset($GLOBALS[$k]); - unset($GLOBALS[$k]); // Double unset to circumvent the zend_hash_del_key_or_index hole in PHP <4.4.3 and <5.1.4 - } - } -} - - -// -// Removes any "bad" characters (characters which mess with the display of a page, are invisible, etc) from user input -// -function forum_remove_bad_characters() -{ - $_GET = remove_bad_characters($_GET); - $_POST = remove_bad_characters($_POST); - $_COOKIE = remove_bad_characters($_COOKIE); - $_REQUEST = remove_bad_characters($_REQUEST); -} - -// -// Removes any "bad" characters (characters which mess with the display of a page, are invisible, etc) from the given string -// See: http://kb.mozillazine.org/Network.IDN.blacklist_chars -// -function remove_bad_characters($array) -{ - static $bad_utf8_chars; - - if (!isset($bad_utf8_chars)) - { - $bad_utf8_chars = array( - "\0" => '', // NULL 0000 * - "\xcc\xb7" => '', // COMBINING SHORT SOLIDUS OVERLAY 0337 * - "\xcc\xb8" => '', // COMBINING LONG SOLIDUS OVERLAY 0338 * - "\xe1\x85\x9F" => '', // HANGUL CHOSEONG FILLER 115F * - "\xe1\x85\xA0" => '', // HANGUL JUNGSEONG FILLER 1160 * - "\xe2\x80\x8b" => '', // ZERO WIDTH SPACE 200B * - "\xe2\x80\x8c" => '', // ZERO WIDTH NON-JOINER 200C - "\xe2\x80\x8d" => '', // ZERO WIDTH JOINER 200D - "\xe2\x80\x8e" => '', // LEFT-TO-RIGHT MARK 200E - "\xe2\x80\x8f" => '', // RIGHT-TO-LEFT MARK 200F - "\xe2\x80\xaa" => '', // LEFT-TO-RIGHT EMBEDDING 202A - "\xe2\x80\xab" => '', // RIGHT-TO-LEFT EMBEDDING 202B - "\xe2\x80\xac" => '', // POP DIRECTIONAL FORMATTING 202C - "\xe2\x80\xad" => '', // LEFT-TO-RIGHT OVERRIDE 202D - "\xe2\x80\xae" => '', // RIGHT-TO-LEFT OVERRIDE 202E - "\xe2\x80\xaf" => '', // NARROW NO-BREAK SPACE 202F * - "\xe2\x81\x9f" => '', // MEDIUM MATHEMATICAL SPACE 205F * - "\xe2\x81\xa0" => '', // WORD JOINER 2060 - "\xe3\x85\xa4" => '', // HANGUL FILLER 3164 * - "\xef\xbb\xbf" => '', // ZERO WIDTH NO-BREAK SPACE FEFF - "\xef\xbe\xa0" => '', // HALFWIDTH HANGUL FILLER FFA0 * - "\xef\xbf\xb9" => '', // INTERLINEAR ANNOTATION ANCHOR FFF9 * - "\xef\xbf\xba" => '', // INTERLINEAR ANNOTATION SEPARATOR FFFA * - "\xef\xbf\xbb" => '', // INTERLINEAR ANNOTATION TERMINATOR FFFB * - "\xef\xbf\xbc" => '', // OBJECT REPLACEMENT CHARACTER FFFC * - "\xef\xbf\xbd" => '', // REPLACEMENT CHARACTER FFFD * - "\xc2\xad" => '-', // SOFT HYPHEN 00AD - "\xE2\x80\x9C" => '"', // LEFT DOUBLE QUOTATION MARK 201C - "\xE2\x80\x9D" => '"', // RIGHT DOUBLE QUOTATION MARK 201D - "\xE2\x80\x98" => '\'', // LEFT SINGLE QUOTATION MARK 2018 - "\xE2\x80\x99" => '\'', // RIGHT SINGLE QUOTATION MARK 2019 - "\xe2\x80\x80" => ' ', // EN QUAD 2000 * - "\xe2\x80\x81" => ' ', // EM QUAD 2001 * - "\xe2\x80\x82" => ' ', // EN SPACE 2002 * - "\xe2\x80\x83" => ' ', // EM SPACE 2003 * - "\xe2\x80\x84" => ' ', // THREE-PER-EM SPACE 2004 * - "\xe2\x80\x85" => ' ', // FOUR-PER-EM SPACE 2005 * - "\xe2\x80\x86" => ' ', // SIX-PER-EM SPACE 2006 * - "\xe2\x80\x87" => ' ', // FIGURE SPACE 2007 * - "\xe2\x80\x88" => ' ', // PUNCTUATION SPACE 2008 * - "\xe2\x80\x89" => ' ', // THIN SPACE 2009 * - "\xe2\x80\x8a" => ' ', // HAIR SPACE 200A * - "\xE3\x80\x80" => ' ', // IDEOGRAPHIC SPACE 3000 * - ); - } - - if (is_array($array)) - return array_map('remove_bad_characters', $array); - - // Strip out any invalid characters - $array = utf8_bad_strip($array); - - // Replace some "bad" characters - $array = str_replace(array_keys($bad_utf8_chars), array_values($bad_utf8_chars), $array); - - return $array; -} - - -// -// Converts the file size in bytes to a human readable file size -// -function file_size($size) -{ - $units = array('B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB'); - - for ($i = 0; $size > 1024; $i++) - $size /= 1024; - - return round($size, 2).' '.$units[$i]; -} - - -// DEBUG FUNCTIONS BELOW - -// -// Display executed queries (if enabled) -// -function display_saved_queries() -{ - global $db, $lang_common; - - // Get the queries so that we can print them out - $saved_queries = $db->get_saved_queries(); - -?> - -
    -

    -
    -
    - - - - - - - - - - - - - - - - - - -
    -
    -
    -
    -'; - - $num_args = func_num_args(); - - for ($i = 0; $i < $num_args; ++$i) - { - print_r(func_get_arg($i)); - echo "\n\n"; - } - - echo ''; - exit; -} diff --git a/upload/include/index.html b/upload/include/index.html deleted file mode 100644 index 89337b2..0000000 --- a/upload/include/index.html +++ /dev/null @@ -1 +0,0 @@ -.. diff --git a/upload/include/parser.php b/upload/include/parser.php deleted file mode 100644 index 9397e8a..0000000 --- a/upload/include/parser.php +++ /dev/null @@ -1,865 +0,0 @@ - 'smile.png', - '=)' => 'smile.png', - ':|' => 'neutral.png', - '=|' => 'neutral.png', - ':(' => 'sad.png', - '=(' => 'sad.png', - ':D' => 'big_smile.png', - '=D' => 'big_smile.png', - ':o' => 'yikes.png', - ':O' => 'yikes.png', - ';)' => 'wink.png', - ':/' => 'hmm.png', - ':P' => 'tongue.png', - ':p' => 'tongue.png', - ':lol:' => 'lol.png', - ':mad:' => 'mad.png', - ':rolleyes:' => 'roll.png', - ':cool:' => 'cool.png'); - -// -// Make sure all BBCodes are lower case and do a little cleanup -// -function preparse_bbcode($text, &$errors, $is_signature = false) -{ - global $pun_config, $lang_common, $re_list; - - if ($is_signature) - { - global $lang_profile; - - if (preg_match('%\[/?(?:quote|code|list|h)\b[^\]]*\]%i', $text)) - $errors[] = $lang_profile['Signature quote/code/list/h']; - } - - // If the message contains a code tag we have to split it up (text within [code][/code] shouldn't be touched) - if (strpos($text, '[code]') !== false && strpos($text, '[/code]') !== false) - { - list($inside, $outside) = split_text($text, '[code]', '[/code]', $errors); - $text = implode("\0", $outside); - } - - // Tidy up lists - $temp = preg_replace($re_list, 'preparse_list_tag(\'$2\', \'$1\', $errors)', $text); - - // If the regex failed - if ($temp === null) - $errors[] = $lang_common['BBCode list size error']; - else - $text = str_replace('*'."\0".']', '*]', $temp); - - if ($pun_config['o_make_links'] == '1') - $text = do_clickable($text); - - // If we split up the message before we have to concatenate it together again (code tags) - if (isset($inside)) - { - $outside = explode("\0", $text); - $text = ''; - - $num_tokens = count($outside); - - for ($i = 0; $i < $num_tokens; ++$i) - { - $text .= $outside[$i]; - if (isset($inside[$i])) - $text .= '[code]'.$inside[$i].'[/code]'; - } - } - - $temp_text = false; - if (empty($errors)) - $temp_text = preparse_tags($text, $errors, $is_signature); - - if ($temp_text !== false) - $text = $temp_text; - - // Remove empty tags - while (($new_text = preg_replace('/\[(b|u|i|h|colou?r|quote|code|img|url|email|list)(?:\=[^\]]*)?\]\[\/\1\]/', '', $text)) !== false) - { - if ($new_text != $text) - $text = $new_text; - else - break; - } - - return pun_trim($text); -} - - -// -// Check the structure of bbcode tags and fix simple mistakes where possible -// -function preparse_tags($text, &$errors, $is_signature = false) -{ - global $lang_common, $pun_config; - - // Start off by making some arrays of bbcode tags and what we need to do with each one - - // List of all the tags - $tags = array('quote', 'code', 'b', 'i', 'u', 'color', 'colour', 'url', 'email', 'img', 'list', '*', 'h'); - // List of tags that we need to check are open (You could not put b,i,u in here then illegal nesting like [b][i][/b][/i] would be allowed) - $tags_opened = $tags; - // and tags we need to check are closed (the same as above, added it just in case) - $tags_closed = $tags; - // Tags we can nest and the depth they can be nested to (only quotes) - $tags_nested = array('quote' => $pun_config['o_quote_depth'], 'list' => 5, '*' => 5); - // Tags to ignore the contents of completely (just code) - $tags_ignore = array('code'); - // Block tags, block tags can only go within another block tag, they cannot be in a normal tag - $tags_block = array('quote', 'code', 'list', 'h', '*'); - // Inline tags, we do not allow new lines in these - $tags_inline = array('b', 'i', 'u', 'color', 'colour', 'h'); - // Tags we trim interior space - $tags_trim = array('img'); - // Tags we remove quotes from the argument - $tags_quotes = array('url', 'email', 'img'); - // Tags we limit bbcode in - $tags_limit_bbcode = array( - '*' => array('b', 'i', 'u', 'color', 'colour', 'url', 'email', 'list', 'img'), - 'list' => array('*'), - 'url' => array('b', 'i', 'u', 'color', 'colour', 'img'), - 'email' => array('b', 'i', 'u', 'color', 'colour', 'img'), - 'img' => array() - ); - // Tags we can automatically fix bad nesting - $tags_fix = array('quote', 'b', 'i', 'u', 'color', 'colour', 'url', 'email', 'h'); - - $split_text = preg_split("/(\[[\*a-zA-Z0-9-\/]*?(?:=.*?)?\])/", $text, -1, PREG_SPLIT_DELIM_CAPTURE|PREG_SPLIT_NO_EMPTY); - - $open_tags = array('post'); - $open_args = array(''); - $opened_tag = 0; - $new_text = ''; - $current_ignore = ''; - $current_nest = ''; - $current_depth = array(); - $limit_bbcode = $tags; - - foreach ($split_text as $current) - { - if ($current == '') - continue; - - // Are we dealing with a tag? - if (substr($current, 0, 1) != '[' || substr($current, -1, 1) != ']') - { - // It's not a bbcode tag so we put it on the end and continue - - // If we are nested too deeply don't add to the end - if ($current_nest) - continue; - - $current = str_replace("\r\n", "\n", $current); - $current = str_replace("\r", "\n", $current); - if (in_array($open_tags[$opened_tag], $tags_inline) && strpos($current, "\n") !== false) - { - // Deal with new lines - $split_current = preg_split("/(\n\n+)/", $current, -1, PREG_SPLIT_DELIM_CAPTURE|PREG_SPLIT_NO_EMPTY); - $current = ''; - - if (!pun_trim($split_current[0], "\n")) // The first part is a linebreak so we need to handle any open tags first - array_unshift($split_current, ''); - - for ($i = 1; $i < count($split_current); $i += 2) - { - $temp_opened = array(); - $temp_opened_arg = array(); - $temp = $split_current[$i - 1]; - while (!empty($open_tags)) - { - $temp_tag = array_pop($open_tags); - $temp_arg = array_pop($open_args); - - if (in_array($temp_tag , $tags_inline)) - { - array_push($temp_opened, $temp_tag); - array_push($temp_opened_arg, $temp_arg); - $temp .= '[/'.$temp_tag.']'; - } - else - { - array_push($open_tags, $temp_tag); - array_push($open_args, $temp_arg); - break; - } - } - $current .= $temp.$split_current[$i]; - $temp = ''; - while (!empty($temp_opened)) - { - $temp_tag = array_pop($temp_opened); - $temp_arg = array_pop($temp_opened_arg); - if (empty($temp_arg)) - $temp .= '['.$temp_tag.']'; - else - $temp .= '['.$temp_tag.'='.$temp_arg.']'; - array_push($open_tags, $temp_tag); - array_push($open_args, $temp_arg); - } - $current .= $temp; - } - - if (array_key_exists($i - 1, $split_current)) - $current .= $split_current[$i - 1]; - } - - if (in_array($open_tags[$opened_tag], $tags_trim)) - $new_text .= pun_trim($current); - else - $new_text .= $current; - - continue; - } - - // Get the name of the tag - $current_arg = ''; - if (strpos($current, '/') === 1) - { - $current_tag = substr($current, 2, -1); - } - else if (strpos($current, '=') === false) - { - $current_tag = substr($current, 1, -1); - } - else - { - $current_tag = substr($current, 1, strpos($current, '=')-1); - $current_arg = substr($current, strpos($current, '=')+1, -1); - } - $current_tag = strtolower($current_tag); - - // Is the tag defined? - if (!in_array($current_tag, $tags)) - { - // It's not a bbcode tag so we put it on the end and continue - if (!$current_nest) - $new_text .= $current; - - continue; - } - - // We definitely have a bbcode tag - - // Make the tag string lower case - if ($equalpos = strpos($current,'=')) - { - // We have an argument for the tag which we don't want to make lowercase - if (strlen(substr($current, $equalpos)) == 2) - { - // Empty tag argument - $errors[] = sprintf($lang_common['BBCode error empty attribute'], $current_tag); - return false; - } - $current = strtolower(substr($current, 0, $equalpos)).substr($current, $equalpos); - } - else - $current = strtolower($current); - - // This is if we are currently in a tag which escapes other bbcode such as code - if ($current_ignore) - { - if ('[/'.$current_ignore.']' == $current) - { - // We've finished the ignored section - $current = '[/'.$current_tag.']'; - $current_ignore = ''; - } - - $new_text .= $current; - - continue; - } - - if ($current_nest) - { - // We are currently too deeply nested so lets see if we are closing the tag or not - if ($current_tag != $current_nest) - continue; - - if (substr($current, 1, 1) == '/') - $current_depth[$current_nest]--; - else - $current_depth[$current_nest]++; - - if ($current_depth[$current_nest] <= $tags_nested[$current_nest]) - $current_nest = ''; - - continue; - } - - // Check the current tag is allowed here - if (!in_array($current_tag, $limit_bbcode) && $current_tag != $open_tags[$opened_tag]) - { - $errors[] = sprintf($lang_common['BBCode error invalid nesting'], $current_tag, $open_tags[$opened_tag]); - return false; - } - - if (substr($current, 1, 1) == '/') - { - // This is if we are closing a tag - - if ($opened_tag == 0 || !in_array($current_tag, $open_tags)) - { - // We tried to close a tag which is not open - if (in_array($current_tag, $tags_opened)) - { - $errors[] = sprintf($lang_common['BBCode error no opening tag'], $current_tag); - return false; - } - } - else - { - // Check nesting - while (true) - { - // Nesting is ok - if ($open_tags[$opened_tag] == $current_tag) - { - array_pop($open_tags); - array_pop($open_args); - $opened_tag--; - break; - } - - // Nesting isn't ok, try to fix it - if (in_array($open_tags[$opened_tag], $tags_closed) && in_array($current_tag, $tags_closed)) - { - if (in_array($current_tag, $open_tags)) - { - $temp_opened = array(); - $temp_opened_arg = array(); - $temp = ''; - while (!empty($open_tags)) - { - $temp_tag = array_pop($open_tags); - $temp_arg = array_pop($open_args); - - if (!in_array($temp_tag, $tags_fix)) - { - // We couldn't fix nesting - $errors[] = sprintf($lang_common['BBCode error no closing tag'], array_pop($temp_opened)); - return false; - } - array_push($temp_opened, $temp_tag); - array_push($temp_opened_arg, $temp_arg); - - if ($temp_tag == $current_tag) - break; - else - $temp .= '[/'.$temp_tag.']'; - } - $current = $temp.$current; - $temp = ''; - array_pop($temp_opened); - array_pop($temp_opened_arg); - - while (!empty($temp_opened)) - { - $temp_tag = array_pop($temp_opened); - $temp_arg = array_pop($temp_opened_arg); - if (empty($temp_arg)) - $temp .= '['.$temp_tag.']'; - else - $temp .= '['.$temp_tag.'='.$temp_arg.']'; - array_push($open_tags, $temp_tag); - array_push($open_args, $temp_arg); - } - $current .= $temp; - $opened_tag--; - break; - } - else - { - // We couldn't fix nesting - $errors[] = sprintf($lang_common['BBCode error no opening tag'], $current_tag); - return false; - } - } - else if (in_array($open_tags[$opened_tag], $tags_closed)) - break; - else - { - array_pop($open_tags); - array_pop($open_args); - $opened_tag--; - } - } - } - - if (in_array($current_tag, array_keys($tags_nested))) - { - if (isset($current_depth[$current_tag])) - $current_depth[$current_tag]--; - } - - if (in_array($open_tags[$opened_tag], array_keys($tags_limit_bbcode))) - $limit_bbcode = $tags_limit_bbcode[$open_tags[$opened_tag]]; - else - $limit_bbcode = $tags; - - $new_text .= $current; - - continue; - } - else - { - // We are opening a tag - if (in_array($current_tag, array_keys($tags_limit_bbcode))) - $limit_bbcode = $tags_limit_bbcode[$current_tag]; - else - $limit_bbcode = $tags; - - if (in_array($current_tag, $tags_block) && !in_array($open_tags[$opened_tag], $tags_block) && $opened_tag != 0) - { - // We tried to open a block tag within a non-block tag - $errors[] = sprintf($lang_common['BBCode error invalid nesting'], $current_tag, $open_tags[$opened_tag]); - return false; - } - - if (in_array($current_tag, $tags_ignore)) - { - // It's an ignore tag so we don't need to worry about what's inside it - $current_ignore = $current_tag; - $new_text .= $current; - continue; - } - - // Deal with nested tags - if (in_array($current_tag, $open_tags) && !in_array($current_tag, array_keys($tags_nested))) - { - // We nested a tag we shouldn't - $errors[] = sprintf($lang_common['BBCode error invalid self-nesting'], $current_tag); - return false; - } - else if (in_array($current_tag, array_keys($tags_nested))) - { - // We are allowed to nest this tag - - if (isset($current_depth[$current_tag])) - $current_depth[$current_tag]++; - else - $current_depth[$current_tag] = 1; - - // See if we are nested too deep - if ($current_depth[$current_tag] > $tags_nested[$current_tag]) - { - $current_nest = $current_tag; - continue; - } - } - - // Remove quotes from arguments for certain tags - if (strpos($current, '=') !== false && in_array($current_tag, $tags_quotes)) - { - $current = preg_replace('#\['.$current_tag.'=("|\'|)(.*?)\\1\]\s*#i', '['.$current_tag.'=$2]', $current); - } - - if (in_array($current_tag, array_keys($tags_limit_bbcode))) - $limit_bbcode = $tags_limit_bbcode[$current_tag]; - - $open_tags[] = $current_tag; - $open_args[] = $current_arg; - $opened_tag++; - $new_text .= $current; - continue; - } - } - - // Check we closed all the tags we needed to - foreach ($tags_closed as $check) - { - if (in_array($check, $open_tags)) - { - // We left an important tag open - $errors[] = sprintf($lang_common['BBCode error no closing tag'], $check); - return false; - } - } - - if ($current_ignore) - { - // We left an ignore tag open - $errors[] = sprintf($lang_common['BBCode error no closing tag'], $current_ignore); - return false; - } - - return $new_text; -} - - -// -// Preparse the contents of [list] bbcode -// -function preparse_list_tag($content, $type = '*', &$errors) -{ - global $lang_common, $re_list; - - if (strlen($type) != 1) - $type = '*'; - - if (strpos($content,'[list') !== false) - { - $content = preg_replace($re_list, 'preparse_list_tag(\'$2\', \'$1\', $errors)', $content); - } - - $items = explode('[*]', str_replace('\"', '"', $content)); - - $content = ''; - foreach ($items as $item) - { - if (pun_trim($item) != '') - $content .= '[*'."\0".']'.str_replace('[/*]', '', pun_trim($item)).'[/*'."\0".']'."\n"; - } - - return '[list='.$type.']'."\n".$content.'[/list]'; -} - - -// -// Split text into chunks ($inside contains all text inside $start and $end, and $outside contains all text outside) -// -function split_text($text, $start, $end, &$errors, $retab = true) -{ - global $pun_config, $lang_common; - - $tokens = explode($start, $text); - - $outside[] = $tokens[0]; - - $num_tokens = count($tokens); - for ($i = 1; $i < $num_tokens; ++$i) - { - $temp = explode($end, $tokens[$i]); - - if (count($temp) != 2) - { - $errors[] = $lang_common['BBCode code problem']; - return array(null, array($text)); - } - $inside[] = $temp[0]; - $outside[] = $temp[1]; - } - - if ($pun_config['o_indent_num_spaces'] != 8 && $retab) - { - $spaces = str_repeat(' ', $pun_config['o_indent_num_spaces']); - $inside = str_replace("\t", $spaces, $inside); - } - - return array($inside, $outside); -} - - -// -// Truncate URL if longer than 55 characters (add http:// or ftp:// if missing) -// -function handle_url_tag($url, $link = '', $bbcode = false) -{ - $url = pun_trim($url); - $full_url = str_replace(array(' ', '\'', '`', '"'), array('%20', '', '', ''), $url); - if (strpos($url, 'www.') === 0) // If it starts with www, we add http:// - $full_url = 'http://'.$full_url; - else if (strpos($url, 'ftp.') === 0) // Else if it starts with ftp, we add ftp:// - $full_url = 'ftp://'.$full_url; - else if (!preg_match('#^([a-z0-9]{3,6})://#', $url)) // Else if it doesn't start with abcdef://, we add http:// - $full_url = 'http://'.$full_url; - - // Ok, not very pretty :-) - if (!$bbcode) - $link = ($link == '' || $link == $url) ? ((utf8_strlen($url) > 55) ? utf8_substr($url, 0 , 39).' … '.utf8_substr($url, -10) : $url) : stripslashes($link); - - if ($bbcode) - { - if ($full_url == $link) - return '[url]'.$link.'[/url]'; - else - return '[url='.$full_url.']'.$link.'[/url]'; - } - else - return ''.$link.''; -} - - -// -// Turns an URL from the [img] tag into an tag or a tag -// -function handle_img_tag($url, $is_signature = false, $alt = null) -{ - global $lang_common, $pun_user; - - if ($alt == null) - $alt = $url; - - $img_tag = '<'.$lang_common['Image link'].'>'; - - if ($is_signature && $pun_user['show_img_sig'] != '0') - $img_tag = ''.pun_htmlspecialchars($alt).''; - else if (!$is_signature && $pun_user['show_img'] != '0') - $img_tag = ''.pun_htmlspecialchars($alt).''; - - return $img_tag; -} - - -// -// Parse the contents of [list] bbcode -// -function handle_list_tag($content, $type = '*') -{ - global $re_list; - - if (strlen($type) != 1) - $type = '*'; - - if (strpos($content,'[list') !== false) - { - $content = preg_replace($re_list, 'handle_list_tag(\'$2\', \'$1\')', $content); - } - - $content = preg_replace('#\s*\[\*\](.*?)\[/\*\]\s*#s', '
  • $1

  • ', pun_trim($content)); - - if ($type == '*') - $content = '
      '.$content.'
    '; - else - if ($type == 'a') - $content = '
      '.$content.'
    '; - else - $content = '
      '.$content.'
    '; - - return '

    '.$content.'

    '; -} - - -// -// Convert BBCodes to their HTML equivalent -// -function do_bbcode($text, $is_signature = false) -{ - global $lang_common, $pun_user, $pun_config, $re_list; - - if (strpos($text, '[quote') !== false) - { - $text = preg_replace('#\[quote\]\s*#', '

    ', $text); - $text = preg_replace('#\[quote=("|"|\'|)(.*?)\\1\]#se', '"

    ".str_replace(array(\'[\', \'\\"\'), array(\'[\', \'"\'), \'$2\')." ".$lang_common[\'wrote\']."

    "', $text); - $text = preg_replace('#\s*\[\/quote\]#S', '

    ', $text); - } - - if (!$is_signature) - { - $pattern[] = $re_list; - $replace[] = 'handle_list_tag(\'$2\', \'$1\')'; - } - - $pattern[] = '#\[b\](.*?)\[/b\]#ms'; - $pattern[] = '#\[i\](.*?)\[/i\]#ms'; - $pattern[] = '#\[u\](.*?)\[/u\]#ms'; - $pattern[] = '#\[colou?r=([a-zA-Z]{3,20}|\#[0-9a-fA-F]{6}|\#[0-9a-fA-F]{3})](.*?)\[/colou?r\]#ms'; - $pattern[] = '#\[h\](.*?)\[/h\]#ms'; - - $replace[] = '$1'; - $replace[] = '$1'; - $replace[] = '$1'; - $replace[] = '$2'; - $replace[] = '

    $1

    '; - - if (($is_signature && $pun_config['p_sig_img_tag'] == '1') || (!$is_signature && $pun_config['p_message_img_tag'] == '1')) - { - $pattern[] = '#\[img\]((ht|f)tps?://)([^\s<"]*?)\[/img\]#e'; - $pattern[] = '#\[img=([^\[]*?)\]((ht|f)tps?://)([^\s<"]*?)\[/img\]#e'; - if ($is_signature) - { - $replace[] = 'handle_img_tag(\'$1$3\', true)'; - $replace[] = 'handle_img_tag(\'$2$4\', true, \'$1\')'; - } - else - { - $replace[] = 'handle_img_tag(\'$1$3\', false)'; - $replace[] = 'handle_img_tag(\'$2$4\', false, \'$1\')'; - } - } - - $pattern[] = '#\[url\]([^\[]*?)\[/url\]#e'; - $pattern[] = '#\[url=([^\[]+?)\](.*?)\[/url\]#e'; - $pattern[] = '#\[email\]([^\[]*?)\[/email\]#'; - $pattern[] = '#\[email=([^\[]+?)\](.*?)\[/email\]#'; - - $replace[] = 'handle_url_tag(\'$1\')'; - $replace[] = 'handle_url_tag(\'$1\', \'$2\')'; - $replace[] = '$1'; - $replace[] = '$2'; - - // This thing takes a while! :) - $text = preg_replace($pattern, $replace, $text); - - return $text; -} - - -// -// Make hyperlinks clickable -// -function do_clickable($text) -{ - $text = ' '.$text; - - $text = preg_replace('#(?<=[\s\]\)])(<)?(\[)?(\()?([\'"]?)(https?|ftp|news){1}://([\w\-]+\.([\w\-]+\.)*\w+(:[0-9]+)?(/[^\s\[]*[^\s.,?!\[;:-])?)\4(?(3)(\)))(?(2)(\]))(?(1)(>))(?![^\s]*\[/(?:url|img)\])#ie', 'stripslashes(\'$1$2$3$4\').handle_url_tag(\'$5://$6\', \'$5://$6\', true).stripslashes(\'$4$10$11$12\')', $text); - $text = preg_replace('#(?<=[\s\]\)])(<)?(\[)?(\()?([\'"]?)(www|ftp)\.(([\w\-]+\.)*\w+(:[0-9]+)?(/[^\s\[]*[^\s.,?!\[;:-])?)\4(?(3)(\)))(?(2)(\]))(?(1)(>))(?![^\s]*\[/(?:url|img)\])#ie', 'stripslashes(\'$1$2$3$4\').handle_url_tag(\'$5.$6\', \'$5.$6\', true).stripslashes(\'$4$10$11$12\')', $text); - - return substr($text, 1); -} - - -// -// Convert a series of smilies to images -// -function do_smilies($text) -{ - global $pun_config, $smilies; - - $text = ' '.$text.' '; - - foreach ($smilies as $smiley_text => $smiley_img) - { - if (strpos($text, $smiley_text) !== false) - $text = preg_replace("#(?<=[>\s])".preg_quote($smiley_text, '#')."(?=\W)#m", ''.substr($smiley_img, 0, strrpos($smiley_img, '.')).'', $text); - } - - return substr($text, 1, -1); -} - - -// -// Parse message text -// -function parse_message($text, $hide_smilies) -{ - global $pun_config, $lang_common, $pun_user; - - if ($pun_config['o_censoring'] == '1') - $text = censor_words($text); - - // Convert applicable characters to HTML entities - $text = pun_htmlspecialchars($text); - - // If the message contains a code tag we have to split it up (text within [code][/code] shouldn't be touched) - if (strpos($text, '[code]') !== false && strpos($text, '[/code]') !== false) - { - list($inside, $outside) = split_text($text, '[code]', '[/code]', $errors); - $text = implode("\0", $outside); - } - - if ($pun_config['p_message_bbcode'] == '1' && strpos($text, '[') !== false && strpos($text, ']') !== false) - $text = do_bbcode($text); - - if ($pun_config['o_smilies'] == '1' && $pun_user['show_smilies'] == '1' && $hide_smilies == '0') - $text = do_smilies($text); - - // Deal with newlines, tabs and multiple spaces - $pattern = array("\n", "\t", ' ', ' '); - $replace = array('
    ', '    ', '  ', '  '); - $text = str_replace($pattern, $replace, $text); - - // If we split up the message before we have to concatenate it together again (code tags) - if (isset($inside)) - { - $outside = explode("\0", $text); - $text = ''; - - $num_tokens = count($outside); - - for ($i = 0; $i < $num_tokens; ++$i) - { - $text .= $outside[$i]; - if (isset($inside[$i])) - // $text .= '

    '.pun_trim($inside[$i], "\n\r").'

    '; - { - $num_lines = (substr_count($inside[$i], "\n")); - $text .= '

    28) ? ' class="vscroll"' : '').'>'.pun_trim($inside[$i], "\n\r").'

    '; - } - } - } - - // Add paragraph tag around post, but make sure there are no empty paragraphs - $text = preg_replace('#
    \s*?
    ((\s*
    )*)#i', "

    $1

    ", $text); - $text = str_replace('


    ', '

    ', $text); - $text = str_replace('

    ', '', '

    '.$text.'

    '); - - return $text; -} - - -// -// Parse signature text -// -function parse_signature($text) -{ - global $pun_config, $lang_common, $pun_user; - - if ($pun_config['o_censoring'] == '1') - $text = censor_words($text); - - // Convert applicable characters to HTML entities - $text = pun_htmlspecialchars($text); - - if ($pun_config['p_sig_bbcode'] == '1' && strpos($text, '[') !== false && strpos($text, ']') !== false) - $text = do_bbcode($text, true); - - if ($pun_config['o_smilies_sig'] == '1' && $pun_user['show_smilies'] == '1') - $text = do_smilies($text); - - - // Deal with newlines, tabs and multiple spaces - $pattern = array("\n", "\t", ' ', ' '); - $replace = array('
    ', '    ', '  ', '  '); - $text = str_replace($pattern, $replace, $text); - - // Add paragraph tag around post, but make sure there are no empty paragraphs - $text = preg_replace('#
    \s*?
    ((\s*
    )*)#i', "

    $1

    ", $text); - $text = str_replace('


    ', '

    ', $text); - $text = str_replace('

    ', '', '

    '.$text.'

    '); - - return $text; -} diff --git a/upload/include/search_idx.php b/upload/include/search_idx.php deleted file mode 100644 index 1214676..0000000 --- a/upload/include/search_idx.php +++ /dev/null @@ -1,311 +0,0 @@ -`"„\|,@_\?%~\+\[\]{}:=\/#\\\\;!\*\.…\s•]+/u', ' ', $text); - - // Replace multiple dashes with just one - $text = preg_replace('/-{2,}/', '-', $text); - - // Fill an array with all the words - $words = array_unique(explode(' ', $text)); - - // Remove any words that should not be indexed - foreach ($words as $key => $value) - { - // If the word shouldn't be indexed, remove it - if (!validate_search_word($value, $idx)) - unset($words[$key]); - } - - return $words; -} - - -// -// Checks if a word is a valid searchable word -// -function validate_search_word($word, $idx) -{ - global $pun_user, $pun_config; - static $stopwords; - - // If the word is a keyword we don't want to index it, but we do want to be allowed to search it - if (is_keyword($word)) - return !$idx; - - $language = isset($pun_user['language']) ? $pun_user['language'] : $pun_config['o_default_lang']; - if (!isset($stopwords)) - { - if (file_exists(PUN_ROOT.'lang/'.$language.'/stopwords.txt')) - { - $stopwords = file(PUN_ROOT.'lang/'.$language.'/stopwords.txt'); - $stopwords = array_map('pun_trim', $stopwords); - $stopwords = array_filter($stopwords); - } - else - $stopwords = array(); - } - - // If it is a stopword it isn't valid - if (in_array($word, $stopwords)) - return false; - - // If the word if CJK we don't want to index it, but we do want to be allowed to search it - if (is_cjk($word)) - return !$idx; - - // Check the word is within the min/max length - $num_chars = pun_strlen($word); - return $num_chars >= PUN_SEARCH_MIN_WORD && $num_chars <= PUN_SEARCH_MAX_WORD; -} - - -// -// Check a given word is a search keyword. -// -function is_keyword($word) -{ - return $word == 'and' || $word == 'or' || $word == 'not'; -} - - -// -// Check if a given word is CJK or Hangul. -// -function is_cjk($word) -{ - return preg_match('/^'.PUN_CJK_HANGUL_REGEX.'+$/u', $word) ? true : false; -} - - -// -// Strip [img] [url] and [email] out of the message so we don't index their contents -// -function strip_bbcode($text) -{ - static $patterns; - - if (!isset($patterns)) - { - $patterns = array( - '%\[img=([^\]]*+)\][^[]*+\[/img\]%' => '$1', // Keep the alt description - '%\[(url|email)=[^\]]*+\]([^[]*+(?:(?!\[/\1\])\[[^[]*+)*)\[/\1\]%' => '$2', // Keep the text - '%\[(img|url|email)\]([^[]*+(?:(?!\[/\1\])\[[^[]*+)*)\[/\1\]%' => '', // Remove the whole thing - ); - } - - return preg_replace(array_keys($patterns), array_values($patterns), $text); -} - - -// -// Updates the search index with the contents of $post_id (and $subject) -// -function update_search_index($mode, $post_id, $message, $subject = null) -{ - global $db_type, $db; - - $message = utf8_strtolower($message); - $subject = utf8_strtolower($subject); - - // Remove any bbcode that we shouldn't index - $message = strip_bbcode($message); - - // Split old and new post/subject to obtain array of 'words' - $words_message = split_words($message, true); - $words_subject = ($subject) ? split_words($subject, true) : array(); - - if ($mode == 'edit') - { - $result = $db->query('SELECT w.id, w.word, m.subject_match FROM '.$db->prefix.'search_words AS w INNER JOIN '.$db->prefix.'search_matches AS m ON w.id=m.word_id WHERE m.post_id='.$post_id, true) or error('Unable to fetch search index words', __FILE__, __LINE__, $db->error()); - - // Declare here to stop array_keys() and array_diff() from complaining if not set - $cur_words['post'] = array(); - $cur_words['subject'] = array(); - - while ($row = $db->fetch_row($result)) - { - $match_in = ($row[2]) ? 'subject' : 'post'; - $cur_words[$match_in][$row[1]] = $row[0]; - } - - $db->free_result($result); - - $words['add']['post'] = array_diff($words_message, array_keys($cur_words['post'])); - $words['add']['subject'] = array_diff($words_subject, array_keys($cur_words['subject'])); - $words['del']['post'] = array_diff(array_keys($cur_words['post']), $words_message); - $words['del']['subject'] = array_diff(array_keys($cur_words['subject']), $words_subject); - } - else - { - $words['add']['post'] = $words_message; - $words['add']['subject'] = $words_subject; - $words['del']['post'] = array(); - $words['del']['subject'] = array(); - } - - unset($words_message); - unset($words_subject); - - // Get unique words from the above arrays - $unique_words = array_unique(array_merge($words['add']['post'], $words['add']['subject'])); - - if (!empty($unique_words)) - { - $result = $db->query('SELECT id, word FROM '.$db->prefix.'search_words WHERE word IN(\''.implode('\',\'', array_map(array($db, 'escape'), $unique_words)).'\')', true) or error('Unable to fetch search index words', __FILE__, __LINE__, $db->error()); - - $word_ids = array(); - while ($row = $db->fetch_row($result)) - $word_ids[$row[1]] = $row[0]; - - $db->free_result($result); - - $new_words = array_diff($unique_words, array_keys($word_ids)); - unset($unique_words); - - if (!empty($new_words)) - { - switch ($db_type) - { - case 'mysql': - case 'mysqli': - case 'mysql_innodb': - case 'mysqli_innodb': - $db->query('INSERT INTO '.$db->prefix.'search_words (word) VALUES(\''.implode('\'),(\'', array_map(array($db, 'escape'), $new_words)).'\')'); - break; - - default: - foreach ($new_words as $word) - $db->query('INSERT INTO '.$db->prefix.'search_words (word) VALUES(\''.$db->escape($word).'\')'); - break; - } - } - - unset($new_words); - } - - // Delete matches (only if editing a post) - foreach ($words['del'] as $match_in => $wordlist) - { - $subject_match = ($match_in == 'subject') ? 1 : 0; - - if (!empty($wordlist)) - { - $sql = ''; - foreach ($wordlist as $word) - $sql .= (($sql != '') ? ',' : '').$cur_words[$match_in][$word]; - - $db->query('DELETE FROM '.$db->prefix.'search_matches WHERE word_id IN('.$sql.') AND post_id='.$post_id.' AND subject_match='.$subject_match) or error('Unable to delete search index word matches', __FILE__, __LINE__, $db->error()); - } - } - - // Add new matches - foreach ($words['add'] as $match_in => $wordlist) - { - $subject_match = ($match_in == 'subject') ? 1 : 0; - - if (!empty($wordlist)) - $db->query('INSERT INTO '.$db->prefix.'search_matches (post_id, word_id, subject_match) SELECT '.$post_id.', id, '.$subject_match.' FROM '.$db->prefix.'search_words WHERE word IN(\''.implode('\',\'', array_map(array($db, 'escape'), $wordlist)).'\')') or error('Unable to insert search index word matches', __FILE__, __LINE__, $db->error()); - } - - unset($words); -} - - -// -// Strip search index of indexed words in $post_ids -// -function strip_search_index($post_ids) -{ - global $db_type, $db; - - switch ($db_type) - { - case 'mysql': - case 'mysqli': - case 'mysql_innodb': - case 'mysqli_innodb': - { - $result = $db->query('SELECT word_id FROM '.$db->prefix.'search_matches WHERE post_id IN('.$post_ids.') GROUP BY word_id') or error('Unable to fetch search index word match', __FILE__, __LINE__, $db->error()); - - if ($db->num_rows($result)) - { - $word_ids = ''; - while ($row = $db->fetch_row($result)) - $word_ids .= ($word_ids != '') ? ','.$row[0] : $row[0]; - - $result = $db->query('SELECT word_id FROM '.$db->prefix.'search_matches WHERE word_id IN('.$word_ids.') GROUP BY word_id HAVING COUNT(word_id)=1') or error('Unable to fetch search index word match', __FILE__, __LINE__, $db->error()); - - if ($db->num_rows($result)) - { - $word_ids = ''; - while ($row = $db->fetch_row($result)) - $word_ids .= ($word_ids != '') ? ','.$row[0] : $row[0]; - - $db->query('DELETE FROM '.$db->prefix.'search_words WHERE id IN('.$word_ids.')') or error('Unable to delete search index word', __FILE__, __LINE__, $db->error()); - } - } - - break; - } - - default: - $db->query('DELETE FROM '.$db->prefix.'search_words WHERE id IN(SELECT word_id FROM '.$db->prefix.'search_matches WHERE word_id IN(SELECT word_id FROM '.$db->prefix.'search_matches WHERE post_id IN('.$post_ids.') GROUP BY word_id) GROUP BY word_id HAVING COUNT(word_id)=1)') or error('Unable to delete from search index', __FILE__, __LINE__, $db->error()); - break; - } - - $db->query('DELETE FROM '.$db->prefix.'search_matches WHERE post_id IN('.$post_ids.')') or error('Unable to delete search index word match', __FILE__, __LINE__, $db->error()); -} diff --git a/upload/include/template/admin.tpl b/upload/include/template/admin.tpl deleted file mode 100644 index 1f6e007..0000000 --- a/upload/include/template/admin.tpl +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - - - - -
    -
    - -
    - -
    -
    -
    - - -
    - - -
    -
    - - - -
    - -
    - - - -
    - -
    -
    - - - diff --git a/upload/include/template/help.tpl b/upload/include/template/help.tpl deleted file mode 100644 index 533d0a0..0000000 --- a/upload/include/template/help.tpl +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - - -
    -
    - -
    - -
    - -
    - -
    - -
    -
    - - - diff --git a/upload/include/template/index.html b/upload/include/template/index.html deleted file mode 100644 index 89337b2..0000000 --- a/upload/include/template/index.html +++ /dev/null @@ -1 +0,0 @@ -.. diff --git a/upload/include/template/main.tpl b/upload/include/template/main.tpl deleted file mode 100644 index f069193..0000000 --- a/upload/include/template/main.tpl +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - - - - -
    -
    - -
    - -
    -
    -
    - - -
    - - -
    -
    - - - -
    - -
    - - - -
    - -
    -
    - - - diff --git a/upload/include/template/maintenance.tpl b/upload/include/template/maintenance.tpl deleted file mode 100644 index 0588caa..0000000 --- a/upload/include/template/maintenance.tpl +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - - -
    -
    - -
    - -
    - -
    - -
    - -
    -
    - - - diff --git a/upload/include/template/redirect.tpl b/upload/include/template/redirect.tpl deleted file mode 100644 index edefa63..0000000 --- a/upload/include/template/redirect.tpl +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - - - -
    -
    - -
    - -
    - -
    - - - -
    - -
    -
    - - - diff --git a/upload/include/utf8/index.html b/upload/include/utf8/index.html deleted file mode 100644 index 89337b2..0000000 --- a/upload/include/utf8/index.html +++ /dev/null @@ -1 +0,0 @@ -.. diff --git a/upload/include/utf8/mbstring/core.php b/upload/include/utf8/mbstring/core.php deleted file mode 100644 index bea1c32..0000000 --- a/upload/include/utf8/mbstring/core.php +++ /dev/null @@ -1,144 +0,0 @@ -.. diff --git a/upload/include/utf8/native/core.php b/upload/include/utf8/native/core.php deleted file mode 100644 index 58636f5..0000000 --- a/upload/include/utf8/native/core.php +++ /dev/null @@ -1,422 +0,0 @@ - -* @link http://www.php.net/manual/en/function.strlen.php -* @link http://www.php.net/manual/en/function.utf8-decode.php -* @param string UTF-8 string -* @return int number of UTF-8 characters in string -* @package utf8 -* @subpackage strings -*/ -function utf8_strlen($str) -{ - return strlen(utf8_decode($str)); -} - -/** -* UTF-8 aware alternative to strpos -* Find position of first occurrence of a string -* Note: This will get alot slower if offset is used -* Note: requires utf8_strlen amd utf8_substr to be loaded -* @param string haystack -* @param string needle (you should validate this with utf8_is_valid) -* @param integer offset in characters (from left) -* @return mixed integer position or FALSE on failure -* @see http://www.php.net/strpos -* @see utf8_strlen -* @see utf8_substr -* @package utf8 -* @subpackage strings -*/ -function utf8_strpos($str, $needle, $offset = false) -{ - if ($offset === false) - { - $ar = explode($needle, $str, 2); - - if (count($ar) > 1) - return utf8_strlen($ar[0]); - - return false; - } - else - { - if (!is_int($offset)) - { - trigger_error('utf8_strpos: Offset must be an integer', E_USER_ERROR); - return false; - } - - $str = utf8_substr($str, $offset); - - if (($pos = utf8_strpos($str, $needle)) !== false) - return $pos + $offset; - - return false; - } -} - -/** -* UTF-8 aware alternative to strrpos -* Find position of last occurrence of a char in a string -* Note: This will get alot slower if offset is used -* Note: requires utf8_substr and utf8_strlen to be loaded -* @param string haystack -* @param string needle (you should validate this with utf8_is_valid) -* @param integer (optional) offset (from left) -* @return mixed integer position or FALSE on failure -* @see http://www.php.net/strrpos -* @see utf8_substr -* @see utf8_strlen -* @package utf8 -* @subpackage strings -*/ -function utf8_strrpos($str, $needle, $offset = false) -{ - if ($offset === false) - { - $ar = explode($needle, $str); - - if (count($ar) > 1) - { - // Pop off the end of the string where the last match was made - array_pop($ar); - $str = join($needle, $ar); - - return utf8_strlen($str); - } - - return false; - } - else - { - if (!is_int($offset)) - { - trigger_error('utf8_strrpos expects parameter 3 to be long', E_USER_WARNING); - return false; - } - - $str = utf8_substr($str, $offset); - - if (($pos = utf8_strrpos($str, $needle)) !== false) - return $pos + $offset; - - return false; - } -} - -/** -* UTF-8 aware alternative to substr -* Return part of a string given character offset (and optionally length) -* -* Note arguments: comparied to substr - if offset or length are -* not integers, this version will not complain but rather massages them -* into an integer. -* -* Note on returned values: substr documentation states false can be -* returned in some cases (e.g. offset > string length) -* mb_substr never returns false, it will return an empty string instead. -* This adopts the mb_substr approach -* -* Note on implementation: PCRE only supports repetitions of less than -* 65536, in order to accept up to MAXINT values for offset and length, -* we'll repeat a group of 65535 characters when needed. -* -* Note on implementation: calculating the number of characters in the -* string is a relatively expensive operation, so we only carry it out when -* necessary. It isn't necessary for +ve offsets and no specified length -* -* @author Chris Smith -* @param string -* @param integer number of UTF-8 characters offset (from left) -* @param integer (optional) length in UTF-8 characters from offset -* @return mixed string or FALSE if failure -* @package utf8 -* @subpackage strings -*/ -function utf8_substr($str, $offset, $length = false) -{ - // Generates E_NOTICE for PHP4 objects, but not PHP5 objects - $str = (string) $str; - $offset = (int) $offset; - - if ($length) - $length = (int) $length; - - // Handle trivial cases - if ($length === 0) - return ''; - if ($offset < 0 && $length < 0 && $length < $offset) - return ''; - - // Normalise negative offsets (we could use a tail - // anchored pattern, but they are horribly slow!) - if ($offset < 0) - { - // See notes - $strlen = utf8_strlen($str); - $offset = $strlen + $offset; - - if ($offset < 0) - $offset = 0; - } - - $Op = ''; - $Lp = ''; - - // Establish a pattern for offset, a - // non-captured group equal in length to offset - if ($offset > 0) - { - $Ox = (int) ($offset / 65535); - $Oy = $offset % 65535; - - if ($Ox) - $Op = '(?:.{65535}){'.$Ox.'}'; - - $Op = '^(?:'.$Op.'.{'.$Oy.'})'; - } - else - $Op = '^'; - - - // Establish a pattern for length - if (!$length) - { - // The rest of the string - $Lp = '(.*)$'; - } - else - { - // See notes - if (!isset($strlen)) - $strlen = strlen(utf8_decode($str)); - - // Another trivial case - if ($offset > $strlen) - return ''; - - if ($length > 0) - { - // Reduce any length that would go passed the end of the string - $length = min($strlen-$offset, $length); - - $Lx = (int)( $length / 65535 ); - $Ly = $length % 65535; - - // Negative length requires a captured group of length characters - if ($Lx) $Lp = '(?:.{65535}){'.$Lx.'}'; - $Lp = '('.$Lp.'.{'.$Ly.'})'; - } - else if ($length < 0) - { - - if ($length < ($offset - $strlen)) - return ''; - - $Lx = (int)((-$length)/65535); - $Ly = (-$length)%65535; - - // Negative length requires ... capture everything except a group of - // -length characters anchored at the tail-end of the string - if ($Lx) - $Lp = '(?:.{65535}){'.$Lx.'}'; - - $Lp = '(.*)(?:'.$Lp.'.{'.$Ly.'})$'; - } - } - - if (!preg_match('#'.$Op.$Lp.'#us', $str, $match)) - return ''; - - return $match[1]; -} - -/** -* UTF-8 aware alternative to strtolower -* Make a string lowercase -* Note: The concept of a characters "case" only exists is some alphabets -* such as Latin, Greek, Cyrillic, Armenian and archaic Georgian - it does -* not exist in the Chinese alphabet, for example. See Unicode Standard -* Annex #21: Case Mappings -* Note: requires utf8_to_unicode and utf8_from_unicode -* @author Andreas Gohr -* @param string -* @return mixed either string in lowercase or FALSE is UTF-8 invalid -* @see http://www.php.net/strtolower -* @see utf8_to_unicode -* @see utf8_from_unicode -* @see http://www.unicode.org/reports/tr21/tr21-5.html -* @see http://dev.splitbrain.org/view/darcs/dokuwiki/inc/utf8.php -* @package utf8 -* @subpackage strings -*/ -function utf8_strtolower($string) -{ - static $UTF8_UPPER_TO_LOWER = false; - - if (!$UTF8_UPPER_TO_LOWER) - { - $UTF8_UPPER_TO_LOWER = array( - 0x0041=>0x0061, 0x03A6=>0x03C6, 0x0162=>0x0163, 0x00C5=>0x00E5, 0x0042=>0x0062, - 0x0139=>0x013A, 0x00C1=>0x00E1, 0x0141=>0x0142, 0x038E=>0x03CD, 0x0100=>0x0101, - 0x0490=>0x0491, 0x0394=>0x03B4, 0x015A=>0x015B, 0x0044=>0x0064, 0x0393=>0x03B3, - 0x00D4=>0x00F4, 0x042A=>0x044A, 0x0419=>0x0439, 0x0112=>0x0113, 0x041C=>0x043C, - 0x015E=>0x015F, 0x0143=>0x0144, 0x00CE=>0x00EE, 0x040E=>0x045E, 0x042F=>0x044F, - 0x039A=>0x03BA, 0x0154=>0x0155, 0x0049=>0x0069, 0x0053=>0x0073, 0x1E1E=>0x1E1F, - 0x0134=>0x0135, 0x0427=>0x0447, 0x03A0=>0x03C0, 0x0418=>0x0438, 0x00D3=>0x00F3, - 0x0420=>0x0440, 0x0404=>0x0454, 0x0415=>0x0435, 0x0429=>0x0449, 0x014A=>0x014B, - 0x0411=>0x0431, 0x0409=>0x0459, 0x1E02=>0x1E03, 0x00D6=>0x00F6, 0x00D9=>0x00F9, - 0x004E=>0x006E, 0x0401=>0x0451, 0x03A4=>0x03C4, 0x0423=>0x0443, 0x015C=>0x015D, - 0x0403=>0x0453, 0x03A8=>0x03C8, 0x0158=>0x0159, 0x0047=>0x0067, 0x00C4=>0x00E4, - 0x0386=>0x03AC, 0x0389=>0x03AE, 0x0166=>0x0167, 0x039E=>0x03BE, 0x0164=>0x0165, - 0x0116=>0x0117, 0x0108=>0x0109, 0x0056=>0x0076, 0x00DE=>0x00FE, 0x0156=>0x0157, - 0x00DA=>0x00FA, 0x1E60=>0x1E61, 0x1E82=>0x1E83, 0x00C2=>0x00E2, 0x0118=>0x0119, - 0x0145=>0x0146, 0x0050=>0x0070, 0x0150=>0x0151, 0x042E=>0x044E, 0x0128=>0x0129, - 0x03A7=>0x03C7, 0x013D=>0x013E, 0x0422=>0x0442, 0x005A=>0x007A, 0x0428=>0x0448, - 0x03A1=>0x03C1, 0x1E80=>0x1E81, 0x016C=>0x016D, 0x00D5=>0x00F5, 0x0055=>0x0075, - 0x0176=>0x0177, 0x00DC=>0x00FC, 0x1E56=>0x1E57, 0x03A3=>0x03C3, 0x041A=>0x043A, - 0x004D=>0x006D, 0x016A=>0x016B, 0x0170=>0x0171, 0x0424=>0x0444, 0x00CC=>0x00EC, - 0x0168=>0x0169, 0x039F=>0x03BF, 0x004B=>0x006B, 0x00D2=>0x00F2, 0x00C0=>0x00E0, - 0x0414=>0x0434, 0x03A9=>0x03C9, 0x1E6A=>0x1E6B, 0x00C3=>0x00E3, 0x042D=>0x044D, - 0x0416=>0x0436, 0x01A0=>0x01A1, 0x010C=>0x010D, 0x011C=>0x011D, 0x00D0=>0x00F0, - 0x013B=>0x013C, 0x040F=>0x045F, 0x040A=>0x045A, 0x00C8=>0x00E8, 0x03A5=>0x03C5, - 0x0046=>0x0066, 0x00DD=>0x00FD, 0x0043=>0x0063, 0x021A=>0x021B, 0x00CA=>0x00EA, - 0x0399=>0x03B9, 0x0179=>0x017A, 0x00CF=>0x00EF, 0x01AF=>0x01B0, 0x0045=>0x0065, - 0x039B=>0x03BB, 0x0398=>0x03B8, 0x039C=>0x03BC, 0x040C=>0x045C, 0x041F=>0x043F, - 0x042C=>0x044C, 0x00DE=>0x00FE, 0x00D0=>0x00F0, 0x1EF2=>0x1EF3, 0x0048=>0x0068, - 0x00CB=>0x00EB, 0x0110=>0x0111, 0x0413=>0x0433, 0x012E=>0x012F, 0x00C6=>0x00E6, - 0x0058=>0x0078, 0x0160=>0x0161, 0x016E=>0x016F, 0x0391=>0x03B1, 0x0407=>0x0457, - 0x0172=>0x0173, 0x0178=>0x00FF, 0x004F=>0x006F, 0x041B=>0x043B, 0x0395=>0x03B5, - 0x0425=>0x0445, 0x0120=>0x0121, 0x017D=>0x017E, 0x017B=>0x017C, 0x0396=>0x03B6, - 0x0392=>0x03B2, 0x0388=>0x03AD, 0x1E84=>0x1E85, 0x0174=>0x0175, 0x0051=>0x0071, - 0x0417=>0x0437, 0x1E0A=>0x1E0B, 0x0147=>0x0148, 0x0104=>0x0105, 0x0408=>0x0458, - 0x014C=>0x014D, 0x00CD=>0x00ED, 0x0059=>0x0079, 0x010A=>0x010B, 0x038F=>0x03CE, - 0x0052=>0x0072, 0x0410=>0x0430, 0x0405=>0x0455, 0x0402=>0x0452, 0x0126=>0x0127, - 0x0136=>0x0137, 0x012A=>0x012B, 0x038A=>0x03AF, 0x042B=>0x044B, 0x004C=>0x006C, - 0x0397=>0x03B7, 0x0124=>0x0125, 0x0218=>0x0219, 0x00DB=>0x00FB, 0x011E=>0x011F, - 0x041E=>0x043E, 0x1E40=>0x1E41, 0x039D=>0x03BD, 0x0106=>0x0107, 0x03AB=>0x03CB, - 0x0426=>0x0446, 0x00DE=>0x00FE, 0x00C7=>0x00E7, 0x03AA=>0x03CA, 0x0421=>0x0441, - 0x0412=>0x0432, 0x010E=>0x010F, 0x00D8=>0x00F8, 0x0057=>0x0077, 0x011A=>0x011B, - 0x0054=>0x0074, 0x004A=>0x006A, 0x040B=>0x045B, 0x0406=>0x0456, 0x0102=>0x0103, - 0x039B=>0x03BB, 0x00D1=>0x00F1, 0x041D=>0x043D, 0x038C=>0x03CC, 0x00C9=>0x00E9, - 0x00D0=>0x00F0, 0x0407=>0x0457, 0x0122=>0x0123); - } - - $uni = utf8_to_unicode($string); - - if (!$uni) - return false; - - $cnt = count($uni); - - for ($i=0; $i < $cnt; $i++) - if (isset($UTF8_UPPER_TO_LOWER[$uni[$i]])) - $uni[$i] = $UTF8_UPPER_TO_LOWER[$uni[$i]]; - - return utf8_from_unicode($uni); -} - -/** -* UTF-8 aware alternative to strtoupper -* Make a string uppercase -* Note: The concept of a characters "case" only exists is some alphabets -* such as Latin, Greek, Cyrillic, Armenian and archaic Georgian - it does -* not exist in the Chinese alphabet, for example. See Unicode Standard -* Annex #21: Case Mappings -* Note: requires utf8_to_unicode and utf8_from_unicode -* @author Andreas Gohr -* @param string -* @return mixed either string in lowercase or FALSE is UTF-8 invalid -* @see http://www.php.net/strtoupper -* @see utf8_to_unicode -* @see utf8_from_unicode -* @see http://www.unicode.org/reports/tr21/tr21-5.html -* @see http://dev.splitbrain.org/view/darcs/dokuwiki/inc/utf8.php -* @package utf8 -* @subpackage strings -*/ -function utf8_strtoupper($string) -{ - static $UTF8_LOWER_TO_UPPER = false; - - if (!$UTF8_LOWER_TO_UPPER) - { - $UTF8_LOWER_TO_UPPER = array( - 0x0061=>0x0041, 0x03C6=>0x03A6, 0x0163=>0x0162, 0x00E5=>0x00C5, 0x0062=>0x0042, - 0x013A=>0x0139, 0x00E1=>0x00C1, 0x0142=>0x0141, 0x03CD=>0x038E, 0x0101=>0x0100, - 0x0491=>0x0490, 0x03B4=>0x0394, 0x015B=>0x015A, 0x0064=>0x0044, 0x03B3=>0x0393, - 0x00F4=>0x00D4, 0x044A=>0x042A, 0x0439=>0x0419, 0x0113=>0x0112, 0x043C=>0x041C, - 0x015F=>0x015E, 0x0144=>0x0143, 0x00EE=>0x00CE, 0x045E=>0x040E, 0x044F=>0x042F, - 0x03BA=>0x039A, 0x0155=>0x0154, 0x0069=>0x0049, 0x0073=>0x0053, 0x1E1F=>0x1E1E, - 0x0135=>0x0134, 0x0447=>0x0427, 0x03C0=>0x03A0, 0x0438=>0x0418, 0x00F3=>0x00D3, - 0x0440=>0x0420, 0x0454=>0x0404, 0x0435=>0x0415, 0x0449=>0x0429, 0x014B=>0x014A, - 0x0431=>0x0411, 0x0459=>0x0409, 0x1E03=>0x1E02, 0x00F6=>0x00D6, 0x00F9=>0x00D9, - 0x006E=>0x004E, 0x0451=>0x0401, 0x03C4=>0x03A4, 0x0443=>0x0423, 0x015D=>0x015C, - 0x0453=>0x0403, 0x03C8=>0x03A8, 0x0159=>0x0158, 0x0067=>0x0047, 0x00E4=>0x00C4, - 0x03AC=>0x0386, 0x03AE=>0x0389, 0x0167=>0x0166, 0x03BE=>0x039E, 0x0165=>0x0164, - 0x0117=>0x0116, 0x0109=>0x0108, 0x0076=>0x0056, 0x00FE=>0x00DE, 0x0157=>0x0156, - 0x00FA=>0x00DA, 0x1E61=>0x1E60, 0x1E83=>0x1E82, 0x00E2=>0x00C2, 0x0119=>0x0118, - 0x0146=>0x0145, 0x0070=>0x0050, 0x0151=>0x0150, 0x044E=>0x042E, 0x0129=>0x0128, - 0x03C7=>0x03A7, 0x013E=>0x013D, 0x0442=>0x0422, 0x007A=>0x005A, 0x0448=>0x0428, - 0x03C1=>0x03A1, 0x1E81=>0x1E80, 0x016D=>0x016C, 0x00F5=>0x00D5, 0x0075=>0x0055, - 0x0177=>0x0176, 0x00FC=>0x00DC, 0x1E57=>0x1E56, 0x03C3=>0x03A3, 0x043A=>0x041A, - 0x006D=>0x004D, 0x016B=>0x016A, 0x0171=>0x0170, 0x0444=>0x0424, 0x00EC=>0x00CC, - 0x0169=>0x0168, 0x03BF=>0x039F, 0x006B=>0x004B, 0x00F2=>0x00D2, 0x00E0=>0x00C0, - 0x0434=>0x0414, 0x03C9=>0x03A9, 0x1E6B=>0x1E6A, 0x00E3=>0x00C3, 0x044D=>0x042D, - 0x0436=>0x0416, 0x01A1=>0x01A0, 0x010D=>0x010C, 0x011D=>0x011C, 0x00F0=>0x00D0, - 0x013C=>0x013B, 0x045F=>0x040F, 0x045A=>0x040A, 0x00E8=>0x00C8, 0x03C5=>0x03A5, - 0x0066=>0x0046, 0x00FD=>0x00DD, 0x0063=>0x0043, 0x021B=>0x021A, 0x00EA=>0x00CA, - 0x03B9=>0x0399, 0x017A=>0x0179, 0x00EF=>0x00CF, 0x01B0=>0x01AF, 0x0065=>0x0045, - 0x03BB=>0x039B, 0x03B8=>0x0398, 0x03BC=>0x039C, 0x045C=>0x040C, 0x043F=>0x041F, - 0x044C=>0x042C, 0x00FE=>0x00DE, 0x00F0=>0x00D0, 0x1EF3=>0x1EF2, 0x0068=>0x0048, - 0x00EB=>0x00CB, 0x0111=>0x0110, 0x0433=>0x0413, 0x012F=>0x012E, 0x00E6=>0x00C6, - 0x0078=>0x0058, 0x0161=>0x0160, 0x016F=>0x016E, 0x03B1=>0x0391, 0x0457=>0x0407, - 0x0173=>0x0172, 0x00FF=>0x0178, 0x006F=>0x004F, 0x043B=>0x041B, 0x03B5=>0x0395, - 0x0445=>0x0425, 0x0121=>0x0120, 0x017E=>0x017D, 0x017C=>0x017B, 0x03B6=>0x0396, - 0x03B2=>0x0392, 0x03AD=>0x0388, 0x1E85=>0x1E84, 0x0175=>0x0174, 0x0071=>0x0051, - 0x0437=>0x0417, 0x1E0B=>0x1E0A, 0x0148=>0x0147, 0x0105=>0x0104, 0x0458=>0x0408, - 0x014D=>0x014C, 0x00ED=>0x00CD, 0x0079=>0x0059, 0x010B=>0x010A, 0x03CE=>0x038F, - 0x0072=>0x0052, 0x0430=>0x0410, 0x0455=>0x0405, 0x0452=>0x0402, 0x0127=>0x0126, - 0x0137=>0x0136, 0x012B=>0x012A, 0x03AF=>0x038A, 0x044B=>0x042B, 0x006C=>0x004C, - 0x03B7=>0x0397, 0x0125=>0x0124, 0x0219=>0x0218, 0x00FB=>0x00DB, 0x011F=>0x011E, - 0x043E=>0x041E, 0x1E41=>0x1E40, 0x03BD=>0x039D, 0x0107=>0x0106, 0x03CB=>0x03AB, - 0x0446=>0x0426, 0x00FE=>0x00DE, 0x00E7=>0x00C7, 0x03CA=>0x03AA, 0x0441=>0x0421, - 0x0432=>0x0412, 0x010F=>0x010E, 0x00F8=>0x00D8, 0x0077=>0x0057, 0x011B=>0x011A, - 0x0074=>0x0054, 0x006A=>0x004A, 0x045B=>0x040B, 0x0456=>0x0406, 0x0103=>0x0102, - 0x03BB=>0x039B, 0x00F1=>0x00D1, 0x043D=>0x041D, 0x03CC=>0x038C, 0x00E9=>0x00C9, - 0x00F0=>0x00D0, 0x0457=>0x0407, 0x0123=>0x0122); - } - - $uni = utf8_to_unicode($string); - - if (!$uni) - return false; - - $cnt = count($uni); - - for ($i=0; $i < $cnt; $i++) - if(isset($UTF8_LOWER_TO_UPPER[$uni[$i]])) - $uni[$i] = $UTF8_LOWER_TO_UPPER[$uni[$i]]; - - return utf8_from_unicode($uni); -} diff --git a/upload/include/utf8/native/index.html b/upload/include/utf8/native/index.html deleted file mode 100644 index 89337b2..0000000 --- a/upload/include/utf8/native/index.html +++ /dev/null @@ -1 +0,0 @@ -.. diff --git a/upload/include/utf8/ord.php b/upload/include/utf8/ord.php deleted file mode 100644 index a333f96..0000000 --- a/upload/include/utf8/ord.php +++ /dev/null @@ -1,78 +0,0 @@ -= 0 && $ord0 <= 127) - return $ord0; - - if (!isset($chr{1})) - { - trigger_error('Short sequence - at least 2 bytes expected, only 1 seen'); - return false; - } - - $ord1 = ord($chr{1}); - if ($ord0 >= 192 && $ord0 <= 223) - return ($ord0 - 192) * 64 + ($ord1 - 128); - - if (!isset($chr{2})) - { - trigger_error('Short sequence - at least 3 bytes expected, only 2 seen'); - return false; - } - - $ord2 = ord($chr{2}); - if ($ord0 >= 224 && $ord0 <= 239) - return ($ord0-224)*4096 + ($ord1-128)*64 + ($ord2-128); - - if (!isset($chr{3})) - { - trigger_error('Short sequence - at least 4 bytes expected, only 3 seen'); - return false; - } - - $ord3 = ord($chr{3}); - if ($ord0>=240 && $ord0<=247) - return ($ord0-240)*262144 + ($ord1-128)*4096 + ($ord2-128)*64 + ($ord3-128); - - if (!isset($chr{4})) - { - trigger_error('Short sequence - at least 5 bytes expected, only 4 seen'); - return false; - } - - $ord4 = ord($chr{4}); - if ($ord0>=248 && $ord0<=251) - return ($ord0-248)*16777216 + ($ord1-128)*262144 + ($ord2-128)*4096 + ($ord3-128)*64 + ($ord4-128); - - if (!isset($chr{5})) - { - trigger_error('Short sequence - at least 6 bytes expected, only 5 seen'); - return false; - } - - if ($ord0>=252 && $ord0<=253) - return ($ord0-252) * 1073741824 + ($ord1-128)*16777216 + ($ord2-128)*262144 + ($ord3-128)*4096 + ($ord4-128)*64 + (ord($c{5})-128); - - if ($ord0 >= 254 && $ord0 <= 255) - { - trigger_error('Invalid UTF-8 with surrogate ordinal '.$ord0); - return false; - } -} diff --git a/upload/include/utf8/str_ireplace.php b/upload/include/utf8/str_ireplace.php deleted file mode 100644 index 7257b0a..0000000 --- a/upload/include/utf8/str_ireplace.php +++ /dev/null @@ -1,72 +0,0 @@ - -* @param string $input -* @param int $length -* @param string $padStr -* @param int $type ( same constants as str_pad ) -* @return string -* @see http://www.php.net/str_pad -* @see utf8_substr -* @package utf8 -* @subpackage strings -*/ -function utf8_str_pad($input, $length, $padStr=' ', $type=STR_PAD_RIGHT) -{ - $inputLen = utf8_strlen($input); - if ($length <= $inputLen) - return $input; - - $padStrLen = utf8_strlen($padStr); - $padLen = $length - $inputLen; - - if ($type == STR_PAD_RIGHT) - { - $repeatTimes = ceil($padLen / $padStrLen); - return utf8_substr($input.str_repeat($padStr, $repeatTimes), 0, $length); - } - - if ($type == STR_PAD_LEFT) - { - $repeatTimes = ceil($padLen / $padStrLen); - return utf8_substr(str_repeat($padStr, $repeatTimes), 0, floor($padLen)).$input; - } - - if ($type == STR_PAD_BOTH) - { - $padLen /= 2; - $padAmountLeft = floor($padLen); - $padAmountRight = ceil($padLen); - $repeatTimesLeft = ceil($padAmountLeft / $padStrLen); - $repeatTimesRight = ceil($padAmountRight / $padStrLen); - - $paddingLeft = utf8_substr(str_repeat($padStr, $repeatTimesLeft), 0, $padAmountLeft); - $paddingRight = utf8_substr(str_repeat($padStr, $repeatTimesRight), 0, $padAmountLeft); - - return $paddingLeft.$input.$paddingRight; - } - - trigger_error('utf8_str_pad: Unknown padding type ('.$type.')', E_USER_ERROR); -} diff --git a/upload/include/utf8/str_split.php b/upload/include/utf8/str_split.php deleted file mode 100644 index 15bc215..0000000 --- a/upload/include/utf8/str_split.php +++ /dev/null @@ -1,33 +0,0 @@ - -* @see http://www.php.net/ltrim -* @see http://dev.splitbrain.org/view/darcs/dokuwiki/inc/utf8.php -* @return string -* @package utf8 -* @subpackage strings -*/ -function utf8_ltrim( $str, $charlist=false) -{ - if($charlist === false) - return ltrim($str); - - // Quote charlist for use in a characterclass - $charlist = preg_replace('!([\\\\\\-\\]\\[/^])!', '\\\${1}', $charlist); - - return preg_replace('/^['.$charlist.']+/u', '', $str); -} - -/** -* UTF-8 aware replacement for rtrim() -* Note: you only need to use this if you are supplying the charlist -* optional arg and it contains UTF-8 characters. Otherwise rtrim will -* work normally on a UTF-8 string -* @author Andreas Gohr -* @see http://www.php.net/rtrim -* @see http://dev.splitbrain.org/view/darcs/dokuwiki/inc/utf8.php -* @return string -* @package utf8 -* @subpackage strings -*/ -function utf8_rtrim($str, $charlist=false) -{ - if($charlist === false) - return rtrim($str); - - // Quote charlist for use in a characterclass - $charlist = preg_replace('!([\\\\\\-\\]\\[/^])!', '\\\${1}', $charlist); - - return preg_replace('/['.$charlist.']+$/u', '', $str); -} - -//--------------------------------------------------------------- -/** -* UTF-8 aware replacement for trim() -* Note: you only need to use this if you are supplying the charlist -* optional arg and it contains UTF-8 characters. Otherwise trim will -* work normally on a UTF-8 string -* @author Andreas Gohr -* @see http://www.php.net/trim -* @see http://dev.splitbrain.org/view/darcs/dokuwiki/inc/utf8.php -* @return string -* @package utf8 -* @subpackage strings -*/ -function utf8_trim( $str, $charlist=false) -{ - if($charlist === false) - return trim($str); - - return utf8_ltrim(utf8_rtrim($str, $charlist), $charlist); -} diff --git a/upload/include/utf8/ucfirst.php b/upload/include/utf8/ucfirst.php deleted file mode 100644 index efee55d..0000000 --- a/upload/include/utf8/ucfirst.php +++ /dev/null @@ -1,35 +0,0 @@ - -* if ( utf8_is_ascii($someString) ) { -* // It's just ASCII - use the native PHP version -* $someString = strtolower($someString); -* } else { -* $someString = utf8_strtolower($someString); -* } -* -* -* @param string -* @return boolean TRUE if it's all ASCII -* @package utf8 -* @subpackage ascii -* @see utf8_is_ascii_ctrl -*/ -function utf8_is_ascii($str) -{ - // Search for any bytes which are outside the ASCII range... - return (preg_match('/(?:[^\x00-\x7F])/', $str) !== 1); -} - -/** -* Tests whether a string contains only 7bit ASCII bytes with device -* control codes omitted. The device control codes can be found on the -* second table here: http://www.w3schools.com/tags/ref_ascii.asp -* -* @param string -* @return boolean TRUE if it's all ASCII without device control codes -* @package utf8 -* @subpackage ascii -* @see utf8_is_ascii -*/ -function utf8_is_ascii_ctrl($str) -{ - // Search for any bytes which are outside the ASCII range, or are device control codes - if (strlen($str) > 0) - return (preg_match('/[^\x09\x0A\x0D\x20-\x7E]/', $str) !== 1); - - return false; -} - -/** -* Strip out all non-7bit ASCII bytes -* If you need to transmit a string to system which you know can only -* support 7bit ASCII, you could use this function. -* @param string -* @return string with non ASCII bytes removed -* @package utf8 -* @subpackage ascii -* @see utf8_strip_non_ascii_ctrl -*/ -function utf8_strip_non_ascii($str) -{ - ob_start(); - - while (preg_match('/^([\x00-\x7F]+)|([^\x00-\x7F]+)/S', $str, $matches)) - { - if (!isset($matches[2])) - echo $matches[0]; - - $str = substr($str, strlen($matches[0])); - } - - $result = ob_get_contents(); - ob_end_clean(); - - return $result; -} - -/** -* Strip out device control codes in the ASCII range -* which are not permitted in XML. Note that this leaves -* multi-byte characters untouched - it only removes device -* control codes -* @see http://hsivonen.iki.fi/producing-xml/#controlchar -* @param string -* @return string control codes removed -*/ -function utf8_strip_ascii_ctrl($str) -{ - ob_start(); - - while (preg_match('/^([^\x00-\x08\x0B\x0C\x0E-\x1F\x7F]+)|([\x00-\x08\x0B\x0C\x0E-\x1F\x7F]+)/S', $str, $matches)) - { - if (!isset($matches[2])) - echo $matches[0]; - - $str = substr($str, strlen($matches[0])); - } - - $result = ob_get_contents(); - ob_end_clean(); - - return $result; -} - -/** -* Strip out all non 7bit ASCII bytes and ASCII device control codes. -* For a list of ASCII device control codes see the 2nd table here: -* http://www.w3schools.com/tags/ref_ascii.asp -* -* @param string -* @return boolean TRUE if it's all ASCII -* @package utf8 -* @subpackage ascii -*/ -function utf8_strip_non_ascii_ctrl($str) -{ - ob_start(); - - while (preg_match( '/^([\x09\x0A\x0D\x20-\x7E]+)|([^\x09\x0A\x0D\x20-\x7E]+)/S', $str, $matches)) - { - if (!isset($matches[2])) - echo $matches[0]; - - $str = substr($str, strlen($matches[0])); - } - - $result = ob_get_contents(); - ob_end_clean(); - - return $result; -} - -/** -* Replace accented UTF-8 characters by unaccented ASCII-7 "equivalents". -* The purpose of this function is to replace characters commonly found in Latin -* alphabets with something more or less equivalent from the ASCII range. This can -* be useful for converting a UTF-8 to something ready for a filename, for example. -* Following the use of this function, you would probably also pass the string -* through utf8_strip_non_ascii to clean out any other non-ASCII chars -* Use the optional parameter to just deaccent lower ($case = -1) or upper ($case = 1) -* letters. Default is to deaccent both cases ($case = 0) -* -* For a more complete implementation of transliteration, see the utf8_to_ascii package -* available from the phputf8 project downloads: -* http://prdownloads.sourceforge.net/phputf8 -* -* @param string UTF-8 string -* @param int (optional) -1 lowercase only, +1 uppercase only, 1 both cases -* @param string UTF-8 with accented characters replaced by ASCII chars -* @return string accented chars replaced with ascii equivalents -* @author Andreas Gohr -* @package utf8 -* @subpackage ascii -*/ -function utf8_accents_to_ascii($str, $case=0) -{ - static $UTF8_LOWER_ACCENTS = null; - static $UTF8_UPPER_ACCENTS = null; - - if($case <= 0) - { - - if (is_null($UTF8_LOWER_ACCENTS)) - { - $UTF8_LOWER_ACCENTS = array( - 'à' => 'a', 'ô' => 'o', 'ď' => 'd', 'ḟ' => 'f', 'ë' => 'e', 'š' => 's', 'ơ' => 'o', - 'ß' => 'ss', 'ă' => 'a', 'ř' => 'r', 'ț' => 't', 'ň' => 'n', 'ā' => 'a', 'ķ' => 'k', - 'ŝ' => 's', 'ỳ' => 'y', 'ņ' => 'n', 'ĺ' => 'l', 'ħ' => 'h', 'ṗ' => 'p', 'ó' => 'o', - 'ú' => 'u', 'ě' => 'e', 'é' => 'e', 'ç' => 'c', 'ẁ' => 'w', 'ċ' => 'c', 'õ' => 'o', - 'ṡ' => 's', 'ø' => 'o', 'ģ' => 'g', 'ŧ' => 't', 'ș' => 's', 'ė' => 'e', 'ĉ' => 'c', - 'ś' => 's', 'î' => 'i', 'ű' => 'u', 'ć' => 'c', 'ę' => 'e', 'ŵ' => 'w', 'ṫ' => 't', - 'ū' => 'u', 'č' => 'c', 'ö' => 'oe', 'è' => 'e', 'ŷ' => 'y', 'ą' => 'a', 'ł' => 'l', - 'ų' => 'u', 'ů' => 'u', 'ş' => 's', 'ğ' => 'g', 'ļ' => 'l', 'ƒ' => 'f', 'ž' => 'z', - 'ẃ' => 'w', 'ḃ' => 'b', 'å' => 'a', 'ì' => 'i', 'ï' => 'i', 'ḋ' => 'd', 'ť' => 't', - 'ŗ' => 'r', 'ä' => 'ae', 'í' => 'i', 'ŕ' => 'r', 'ê' => 'e', 'ü' => 'ue', 'ò' => 'o', - 'ē' => 'e', 'ñ' => 'n', 'ń' => 'n', 'ĥ' => 'h', 'ĝ' => 'g', 'đ' => 'd', 'ĵ' => 'j', - 'ÿ' => 'y', 'ũ' => 'u', 'ŭ' => 'u', 'ư' => 'u', 'ţ' => 't', 'ý' => 'y', 'ő' => 'o', - 'â' => 'a', 'ľ' => 'l', 'ẅ' => 'w', 'ż' => 'z', 'ī' => 'i', 'ã' => 'a', 'ġ' => 'g', - 'ṁ' => 'm', 'ō' => 'o', 'ĩ' => 'i', 'ù' => 'u', 'į' => 'i', 'ź' => 'z', 'á' => 'a', - 'û' => 'u', 'þ' => 'th', 'ð' => 'dh', 'æ' => 'ae', 'µ' => 'u', 'ĕ' => 'e', - ); - } - - $str = str_replace(array_keys($UTF8_LOWER_ACCENTS), array_values($UTF8_LOWER_ACCENTS), $str); - } - - if($case >= 0) - { - if (is_null($UTF8_UPPER_ACCENTS)) - { - $UTF8_UPPER_ACCENTS = array( - 'À' => 'A', 'Ô' => 'O', 'Ď' => 'D', 'Ḟ' => 'F', 'Ë' => 'E', 'Š' => 'S', 'Ơ' => 'O', - 'Ă' => 'A', 'Ř' => 'R', 'Ț' => 'T', 'Ň' => 'N', 'Ā' => 'A', 'Ķ' => 'K', - 'Ŝ' => 'S', 'Ỳ' => 'Y', 'Ņ' => 'N', 'Ĺ' => 'L', 'Ħ' => 'H', 'Ṗ' => 'P', 'Ó' => 'O', - 'Ú' => 'U', 'Ě' => 'E', 'É' => 'E', 'Ç' => 'C', 'Ẁ' => 'W', 'Ċ' => 'C', 'Õ' => 'O', - 'Ṡ' => 'S', 'Ø' => 'O', 'Ģ' => 'G', 'Ŧ' => 'T', 'Ș' => 'S', 'Ė' => 'E', 'Ĉ' => 'C', - 'Ś' => 'S', 'Î' => 'I', 'Ű' => 'U', 'Ć' => 'C', 'Ę' => 'E', 'Ŵ' => 'W', 'Ṫ' => 'T', - 'Ū' => 'U', 'Č' => 'C', 'Ö' => 'Oe', 'È' => 'E', 'Ŷ' => 'Y', 'Ą' => 'A', 'Ł' => 'L', - 'Ų' => 'U', 'Ů' => 'U', 'Ş' => 'S', 'Ğ' => 'G', 'Ļ' => 'L', 'Ƒ' => 'F', 'Ž' => 'Z', - 'Ẃ' => 'W', 'Ḃ' => 'B', 'Å' => 'A', 'Ì' => 'I', 'Ï' => 'I', 'Ḋ' => 'D', 'Ť' => 'T', - 'Ŗ' => 'R', 'Ä' => 'Ae', 'Í' => 'I', 'Ŕ' => 'R', 'Ê' => 'E', 'Ü' => 'Ue', 'Ò' => 'O', - 'Ē' => 'E', 'Ñ' => 'N', 'Ń' => 'N', 'Ĥ' => 'H', 'Ĝ' => 'G', 'Đ' => 'D', 'Ĵ' => 'J', - 'Ÿ' => 'Y', 'Ũ' => 'U', 'Ŭ' => 'U', 'Ư' => 'U', 'Ţ' => 'T', 'Ý' => 'Y', 'Ő' => 'O', - 'Â' => 'A', 'Ľ' => 'L', 'Ẅ' => 'W', 'Ż' => 'Z', 'Ī' => 'I', 'Ã' => 'A', 'Ġ' => 'G', - 'Ṁ' => 'M', 'Ō' => 'O', 'Ĩ' => 'I', 'Ù' => 'U', 'Į' => 'I', 'Ź' => 'Z', 'Á' => 'A', - 'Û' => 'U', 'Þ' => 'Th', 'Ð' => 'Dh', 'Æ' => 'Ae', 'Ĕ' => 'E', - ); - } - - $str = str_replace(array_keys($UTF8_UPPER_ACCENTS), array_values($UTF8_UPPER_ACCENTS), $str); - } - - return $str; -} diff --git a/upload/include/utf8/utils/bad.php b/upload/include/utf8/utils/bad.php deleted file mode 100644 index 78e9d17..0000000 --- a/upload/include/utf8/utils/bad.php +++ /dev/null @@ -1,435 +0,0 @@ - 0) - return $badList; - - return false; -} - -/** -* Strips out any bad bytes from a UTF-8 string and returns the rest -* PCRE Pattern to locate bad bytes in a UTF-8 string -* Comes from W3 FAQ: Multilingual Forms -* Note: modified to include full ASCII range including control chars -* @see http://www.w3.org/International/questions/qa-forms-utf-8 -* @param string -* @return string -* @package utf8 -* @subpackage bad -*/ -function utf8_bad_strip($str) -{ - $UTF8_BAD = - '([\x00-\x7F]'. # ASCII (including control chars) - '|[\xC2-\xDF][\x80-\xBF]'. # Non-overlong 2-byte - '|\xE0[\xA0-\xBF][\x80-\xBF]'. # Excluding overlongs - '|[\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}'. # Straight 3-byte - '|\xED[\x80-\x9F][\x80-\xBF]'. # Excluding surrogates - '|\xF0[\x90-\xBF][\x80-\xBF]{2}'. # Planes 1-3 - '|[\xF1-\xF3][\x80-\xBF]{3}'. # Planes 4-15 - '|\xF4[\x80-\x8F][\x80-\xBF]{2}'. # Plane 16 - '|(.{1}))'; # Invalid byte - - ob_start(); - - while (preg_match('/'.$UTF8_BAD.'/S', $str, $matches)) - { - if (!isset($matches[2])) - echo $matches[0]; - - $str = substr($str, strlen($matches[0])); - } - - $result = ob_get_contents(); - ob_end_clean(); - - return $result; -} - -/** -* Replace bad bytes with an alternative character - ASCII character -* recommended is replacement char -* PCRE Pattern to locate bad bytes in a UTF-8 string -* Comes from W3 FAQ: Multilingual Forms -* Note: modified to include full ASCII range including control chars -* @see http://www.w3.org/International/questions/qa-forms-utf-8 -* @param string to search -* @param string to replace bad bytes with (defaults to '?') - use ASCII -* @return string -* @package utf8 -* @subpackage bad -*/ -function utf8_bad_replace($str, $replace='?') -{ - $UTF8_BAD = - '([\x00-\x7F]'. # ASCII (including control chars) - '|[\xC2-\xDF][\x80-\xBF]'. # Non-overlong 2-byte - '|\xE0[\xA0-\xBF][\x80-\xBF]'. # Excluding overlongs - '|[\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}'. # Straight 3-byte - '|\xED[\x80-\x9F][\x80-\xBF]'. # Excluding surrogates - '|\xF0[\x90-\xBF][\x80-\xBF]{2}'. # Planes 1-3 - '|[\xF1-\xF3][\x80-\xBF]{3}'. # Planes 4-15 - '|\xF4[\x80-\x8F][\x80-\xBF]{2}'. # Plane 16 - '|(.{1}))'; # Invalid byte - - ob_start(); - - while (preg_match('/'.$UTF8_BAD.'/S', $str, $matches)) - { - if (!isset($matches[2])) - echo $matches[0]; - else - echo $replace; - - $str = substr($str, strlen($matches[0])); - } - - $result = ob_get_contents(); - ob_end_clean(); - - return $result; -} - -/** -* Return code from utf8_bad_identify() when a five octet sequence is detected. -* Note: 5 octets sequences are valid UTF-8 but are not supported by Unicode so -* do not represent a useful character -* @see utf8_bad_identify -* @package utf8 -* @subpackage bad -*/ -define('UTF8_BAD_5OCTET', 1); - -/** -* Return code from utf8_bad_identify() when a six octet sequence is detected. -* Note: 6 octets sequences are valid UTF-8 but are not supported by Unicode so -* do not represent a useful character -* @see utf8_bad_identify -* @package utf8 -* @subpackage bad -*/ -define('UTF8_BAD_6OCTET', 2); - -/** -* Return code from utf8_bad_identify(). -* Invalid octet for use as start of multi-byte UTF-8 sequence -* @see utf8_bad_identify -* @package utf8 -* @subpackage bad -*/ -define('UTF8_BAD_SEQID', 3); - -/** -* Return code from utf8_bad_identify(). -* From Unicode 3.1, non-shortest form is illegal -* @see utf8_bad_identify -* @package utf8 -* @subpackage bad -*/ -define('UTF8_BAD_NONSHORT', 4); - -/** -* Return code from utf8_bad_identify(). -* From Unicode 3.2, surrogate characters are illegal -* @see utf8_bad_identify -* @package utf8 -* @subpackage bad -*/ -define('UTF8_BAD_SURROGATE', 5); - -/** -* Return code from utf8_bad_identify(). -* Codepoints outside the Unicode range are illegal -* @see utf8_bad_identify -* @package utf8 -* @subpackage bad -*/ -define('UTF8_BAD_UNIOUTRANGE', 6); - -/** -* Return code from utf8_bad_identify(). -* Incomplete multi-octet sequence -* Note: this is kind of a "catch-all" -* @see utf8_bad_identify -* @package utf8 -* @subpackage bad -*/ -define('UTF8_BAD_SEQINCOMPLETE', 7); - -/** -* Reports on the type of bad byte found in a UTF-8 string. Returns a -* status code on the first bad byte found -* @author -* @param string UTF-8 encoded string -* @return mixed integer constant describing problem or FALSE if valid UTF-8 -* @see utf8_bad_explain -* @see http://hsivonen.iki.fi/php-utf8/ -* @package utf8 -* @subpackage bad -*/ -function utf8_bad_identify($str, &$i) -{ - $mState = 0; // Cached expected number of octets after the current octet - // until the beginning of the next UTF8 character sequence - $mUcs4 = 0; // Cached Unicode character - $mBytes = 1; // Cached expected number of octets in the current sequence - - $len = strlen($str); - - for($i=0; $i < $len; $i++) - { - $in = ord($str{$i}); - - if ( $mState == 0) - { - // When mState is zero we expect either a US-ASCII character or a multi-octet sequence. - if (0 == (0x80 & ($in))) - { - // US-ASCII, pass straight through. - $mBytes = 1; - } - else if (0xC0 == (0xE0 & ($in))) - { - // First octet of 2 octet sequence - $mUcs4 = ($in); - $mUcs4 = ($mUcs4 & 0x1F) << 6; - $mState = 1; - $mBytes = 2; - } - else if (0xE0 == (0xF0 & ($in))) - { - // First octet of 3 octet sequence - $mUcs4 = ($in); - $mUcs4 = ($mUcs4 & 0x0F) << 12; - $mState = 2; - $mBytes = 3; - } - else if (0xF0 == (0xF8 & ($in))) - { - // First octet of 4 octet sequence - $mUcs4 = ($in); - $mUcs4 = ($mUcs4 & 0x07) << 18; - $mState = 3; - $mBytes = 4; - } - else if (0xF8 == (0xFC & ($in))) - { - /* First octet of 5 octet sequence. - * - * This is illegal because the encoded codepoint must be either - * (a) not the shortest form or - * (b) outside the Unicode range of 0-0x10FFFF. - */ - return UTF8_BAD_5OCTET; - } - else if (0xFC == (0xFE & ($in))) - { - // First octet of 6 octet sequence, see comments for 5 octet sequence. - return UTF8_BAD_6OCTET; - } - else - { - // Current octet is neither in the US-ASCII range nor a legal first - // octet of a multi-octet sequence. - return UTF8_BAD_SEQID; - } - } - else - { - // When mState is non-zero, we expect a continuation of the multi-octet sequence - if (0x80 == (0xC0 & ($in))) - { - // Legal continuation. - $shift = ($mState - 1) * 6; - $tmp = $in; - $tmp = ($tmp & 0x0000003F) << $shift; - $mUcs4 |= $tmp; - - /** - * End of the multi-octet sequence. mUcs4 now contains the final - * Unicode codepoint to be output - */ - if (0 == --$mState) - { - // From Unicode 3.1, non-shortest form is illegal - if (((2 == $mBytes) && ($mUcs4 < 0x0080)) || - ((3 == $mBytes) && ($mUcs4 < 0x0800)) || - ((4 == $mBytes) && ($mUcs4 < 0x10000)) ) - return UTF8_BAD_NONSHORT; - else if (($mUcs4 & 0xFFFFF800) == 0xD800) // From Unicode 3.2, surrogate characters are illegal - return UTF8_BAD_SURROGATE; - else if ($mUcs4 > 0x10FFFF) // Codepoints outside the Unicode range are illegal - return UTF8_BAD_UNIOUTRANGE; - - // Initialize UTF8 cache - $mState = 0; - $mUcs4 = 0; - $mBytes = 1; - } - - } - else - { - // ((0xC0 & (*in) != 0x80) && (mState != 0)) - // Incomplete multi-octet sequence. - $i--; - return UTF8_BAD_SEQINCOMPLETE; - } - } - } - - // Incomplete multi-octet sequence - if ($mState != 0) - { - $i--; - return UTF8_BAD_SEQINCOMPLETE; - } - - // No bad octets found - $i = null; - return false; -} - -/** -* Takes a return code from utf8_bad_identify() are returns a message -* (in English) explaining what the problem is. -* @param int return code from utf8_bad_identify -* @return mixed string message or FALSE if return code unknown -* @see utf8_bad_identify -* @package utf8 -* @subpackage bad -*/ -function utf8_bad_explain($code) -{ - switch ($code) - { - case UTF8_BAD_5OCTET: - return 'Five octet sequences are valid UTF-8 but are not supported by Unicode'; - break; - - case UTF8_BAD_6OCTET: - return 'Six octet sequences are valid UTF-8 but are not supported by Unicode'; - break; - - case UTF8_BAD_SEQID: - return 'Invalid octet for use as start of multi-byte UTF-8 sequence'; - break; - - case UTF8_BAD_NONSHORT: - return 'From Unicode 3.1, non-shortest form is illegal'; - break; - - case UTF8_BAD_SURROGATE: - return 'From Unicode 3.2, surrogate characters are illegal'; - break; - - case UTF8_BAD_UNIOUTRANGE: - return 'Codepoints outside the Unicode range are illegal'; - break; - - case UTF8_BAD_SEQINCOMPLETE: - return 'Incomplete multi-octet sequence'; - break; - } - - trigger_error('Unknown error code: '.$code, E_USER_WARNING); - - return false; -} diff --git a/upload/include/utf8/utils/index.html b/upload/include/utf8/utils/index.html deleted file mode 100644 index 89337b2..0000000 --- a/upload/include/utf8/utils/index.html +++ /dev/null @@ -1 +0,0 @@ -.. diff --git a/upload/include/utf8/utils/patterns.php b/upload/include/utf8/utils/patterns.php deleted file mode 100644 index 5a85a4f..0000000 --- a/upload/include/utf8/utils/patterns.php +++ /dev/null @@ -1,67 +0,0 @@ - -* @param string string to locate index in -* @param int (n times) -* @return mixed - int if only one input int, array if more -* @return boolean TRUE if it's all ASCII -* @package utf8 -* @subpackage position -*/ -function utf8_byte_position() -{ - $args = func_get_args(); - $str =& array_shift($args); - - if (!is_string($str)) - return false; - - $result = array(); - $prev = array(0, 0); // Trivial byte index, character offset pair - $i = utf8_locate_next_chr($str, 300); // Use a short piece of str to estimate bytes per character. $i (& $j) -> byte indexes into $str - $c = strlen(utf8_decode(substr($str, 0, $i))); // $c -> character offset into $str - - // Deal with arguments from lowest to highest - sort($args); - - foreach ($args as $offset) - { - // Sanity checks FIXME - - // 0 is an easy check - if ($offset == 0) - { - $result[] = 0; continue; - } - - // Ensure no endless looping - $safety_valve = 50; - - do - { - if (($c - $prev[1]) == 0) - { - // Hack: gone past end of string - $error = 0; - $i = strlen($str); - break; - } - - $j = $i + (int)(($offset-$c) * ($i - $prev[0]) / ($c - $prev[1])); - $j = utf8_locate_next_chr($str, $j); // Correct to utf8 character boundary - $prev = array($i,$c); // Save the index, offset for use next iteration - - if ($j > $i) - $c += strlen(utf8_decode(substr($str, $i, $j-$i))); // Determine new character offset - else - $c -= strlen(utf8_decode(substr($str, $j, $i-$j))); // Ditto - - $error = abs($c-$offset); - $i = $j; // Ready for next time around - } - while (($error > 7) && --$safety_valve); // From 7 it is faster to iterate over the string - - if ($error && $error <= 7) - { - if ($c < $offset) - { - // Move up - while ($error--) - $i = utf8_locate_next_chr($str, ++$i); - } - else - { - // Move down - while ($error--) - $i = utf8_locate_current_chr($str, --$i); - } - - // Ready for next arg - $c = $offset; - } - - $result[] = $i; - } - - if (count($result) == 1) - return $result[0]; - - return $result; -} - -/** -* Given a string and any byte index, returns the byte index -* of the start of the current UTF-8 character, relative to supplied -* position. If the current character begins at the same place as the -* supplied byte index, that byte index will be returned. Otherwise -* this function will step backwards, looking for the index where -* curent UTF-8 character begins -* @author Chris Smith -* @param string -* @param int byte index in the string -* @return int byte index of start of next UTF-8 character -* @package utf8 -* @subpackage position -*/ -function utf8_locate_current_chr( &$str, $idx ) -{ - if ($idx <= 0) - return 0; - - $limit = strlen($str); - if ($idx >= $limit) - return $limit; - - // Binary value for any byte after the first in a multi-byte UTF-8 character - // will be like 10xxxxxx so & 0xC0 can be used to detect this kind - // of byte - assuming well formed UTF-8 - while ($idx && ((ord($str[$idx]) & 0xC0) == 0x80)) - $idx--; - - return $idx; -} - -/** -* Given a string and any byte index, returns the byte index -* of the start of the next UTF-8 character, relative to supplied -* position. If the next character begins at the same place as the -* supplied byte index, that byte index will be returned. -* @author Chris Smith -* @param string -* @param int byte index in the string -* @return int byte index of start of next UTF-8 character -* @package utf8 -* @subpackage position -*/ -function utf8_locate_next_chr(&$str, $idx) -{ - if ($idx <= 0) - return 0; - - $limit = strlen($str); - if ($idx >= $limit) - return $limit; - - // Binary value for any byte after the first in a multi-byte UTF-8 character - // will be like 10xxxxxx so & 0xC0 can be used to detect this kind - // of byte - assuming well formed UTF-8 - while (($idx < $limit) && ((ord($str[$idx]) & 0xC0) == 0x80)) - $idx++; - - return $idx; -} diff --git a/upload/include/utf8/utils/specials.php b/upload/include/utf8/utils/specials.php deleted file mode 100644 index 69219dc..0000000 --- a/upload/include/utf8/utils/specials.php +++ /dev/null @@ -1,131 +0,0 @@ - -* @param string $string The UTF8 string to strip of special chars -* @param string (optional) $repl Replace special with this string -* @return string with common non-alphanumeric characters removed -* @see utf8_specials_pattern -*/ -function utf8_strip_specials($string, $repl='') -{ - return preg_replace(utf8_specials_pattern(), $repl, $string); -} diff --git a/upload/include/utf8/utils/unicode.php b/upload/include/utf8/utils/unicode.php deleted file mode 100644 index f0e86cb..0000000 --- a/upload/include/utf8/utils/unicode.php +++ /dev/null @@ -1,241 +0,0 @@ - 0xFFFF. Occurrances of the BOM are ignored. Surrogates -* are not allowed. -* Returns false if the input string isn't a valid UTF-8 octet sequence -* and raises a PHP error at level E_USER_WARNING -* Note: this function has been modified slightly in this library to -* trigger errors on encountering bad bytes -* @author -* @param string UTF-8 encoded string -* @return mixed array of unicode code points or FALSE if UTF-8 invalid -* @see utf8_from_unicode -* @see http://hsivonen.iki.fi/php-utf8/ -* @package utf8 -* @subpackage unicode -*/ -function utf8_to_unicode($str) -{ - $mState = 0; // Cached expected number of octets after the current octet - // until the beginning of the next UTF8 character sequence - $mUcs4 = 0; // Cached Unicode character - $mBytes = 1; // Cached expected number of octets in the current sequence - - $out = array(); - $len = strlen($str); - - for($i = 0; $i < $len; $i++) - { - $in = ord($str[$i]); - - if ($mState == 0) - { - // When mState is zero we expect either a US-ASCII character or a multi-octet sequence. - if (0 == (0x80 & ($in))) - { - // US-ASCII, pass straight through. - $out[] = $in; - $mBytes = 1; - } - else if (0xC0 == (0xE0 & ($in))) - { - // First octet of 2 octet sequence - $mUcs4 = ($in); - $mUcs4 = ($mUcs4 & 0x1F) << 6; - $mState = 1; - $mBytes = 2; - } - else if (0xE0 == (0xF0 & ($in))) - { - // First octet of 3 octet sequence - $mUcs4 = ($in); - $mUcs4 = ($mUcs4 & 0x0F) << 12; - $mState = 2; - $mBytes = 3; - } - else if (0xF0 == (0xF8 & ($in))) - { - // First octet of 4 octet sequence - $mUcs4 = ($in); - $mUcs4 = ($mUcs4 & 0x07) << 18; - $mState = 3; - $mBytes = 4; - } - else if (0xF8 == (0xFC & ($in))) - { - /* First octet of 5 octet sequence. - * - * This is illegal because the encoded codepoint must be either - * (a) not the shortest form or - * (b) outside the Unicode range of 0-0x10FFFF. - * Rather than trying to resynchronize, we will carry on until the end - * of the sequence and let the later error handling code catch it. - */ - $mUcs4 = ($in); - $mUcs4 = ($mUcs4 & 0x03) << 24; - $mState = 4; - $mBytes = 5; - } - else if (0xFC == (0xFE & ($in))) - { - // First octet of 6 octet sequence, see comments for 5 octet sequence. - $mUcs4 = ($in); - $mUcs4 = ($mUcs4 & 1) << 30; - $mState = 5; - $mBytes = 6; - } - else - { - // Current octet is neither in the US-ASCII range nor a legal first octet of a multi-octet sequence - trigger_error('utf8_to_unicode: Illegal sequence identifier in UTF-8 at byte '.$i, E_USER_WARNING); - return false; - } - } - else - { - // When mState is non-zero, we expect a continuation of the multi-octet sequence - if (0x80 == (0xC0 & ($in))) - { - // Legal continuation. - $shift = ($mState - 1) * 6; - $tmp = $in; - $tmp = ($tmp & 0x0000003F) << $shift; - $mUcs4 |= $tmp; - - /** - * End of the multi-octet sequence. mUcs4 now contains the final - * Unicode codepoint to be output - */ - if (0 == --$mState) - { - /* - * Check for illegal sequences and codepoints. - */ - // From Unicode 3.1, non-shortest form is illegal - if (((2 == $mBytes) && ($mUcs4 < 0x0080)) || ((3 == $mBytes) && ($mUcs4 < 0x0800)) || - ((4 == $mBytes) && ($mUcs4 < 0x10000)) || (4 < $mBytes) || - // From Unicode 3.2, surrogate characters are illegal - (($mUcs4 & 0xFFFFF800) == 0xD800) || - // Codepoints outside the Unicode range are illegal - ($mUcs4 > 0x10FFFF)) - { - trigger_error('utf8_to_unicode: Illegal sequence or codepoint in UTF-8 at byte '.$i, E_USER_WARNING); - return false; - } - - // BOM is legal but we don't want to output it - if (0xFEFF != $mUcs4) - $out[] = $mUcs4; - - // Initialize UTF8 cache - $mState = 0; - $mUcs4 = 0; - $mBytes = 1; - } - - } - else - { - /* ((0xC0 & (*in) != 0x80) && (mState != 0)) - Incomplete multi-octet sequence. */ - trigger_error('utf8_to_unicode: Incomplete multi-octet sequence in UTF-8 at byte '.$i, E_USER_WARNING); - return false; - } - } - } - - return $out; -} - -/** -* Takes an array of ints representing the Unicode characters and returns -* a UTF-8 string. Astral planes are supported ie. the ints in the -* input can be > 0xFFFF. Occurrances of the BOM are ignored. Surrogates -* are not allowed. -* Returns false if the input array contains ints that represent -* surrogates or are outside the Unicode range -* and raises a PHP error at level E_USER_WARNING -* Note: this function has been modified slightly in this library to use -* output buffering to concatenate the UTF-8 string (faster) as well as -* reference the array by it's keys -* @param array of unicode code points representing a string -* @return mixed UTF-8 string or FALSE if array contains invalid code points -* @author -* @see utf8_to_unicode -* @see http://hsivonen.iki.fi/php-utf8/ -* @package utf8 -* @subpackage unicode -*/ -function utf8_from_unicode($arr) -{ - ob_start(); - - foreach (array_keys($arr) as $k) - { - if ( ($arr[$k] >= 0) && ($arr[$k] <= 0x007f) ) // ASCII range (including control chars) - { - echo chr($arr[$k]); - } - else if ($arr[$k] <= 0x07ff) //2 byte sequence - { - echo chr(0xc0 | ($arr[$k] >> 6)); - echo chr(0x80 | ($arr[$k] & 0x003f)); - } - else if($arr[$k] == 0xFEFF) // Byte order mark (skip) - { - // Nop -- zap the BOM - } - else if ($arr[$k] >= 0xD800 && $arr[$k] <= 0xDFFF) // Test for illegal surrogates - { - // Found a surrogate - trigger_error('utf8_from_unicode: Illegal surrogate at index: '.$k.', value: '.$arr[$k], E_USER_WARNING); - - return false; - } - else if ($arr[$k] <= 0xffff) // 3 byte sequence - { - echo chr(0xe0 | ($arr[$k] >> 12)); - echo chr(0x80 | (($arr[$k] >> 6) & 0x003f)); - echo chr(0x80 | ($arr[$k] & 0x003f)); - } - else if ($arr[$k] <= 0x10ffff) // 4 byte sequence - { - echo chr(0xf0 | ($arr[$k] >> 18)); - echo chr(0x80 | (($arr[$k] >> 12) & 0x3f)); - echo chr(0x80 | (($arr[$k] >> 6) & 0x3f)); - echo chr(0x80 | ($arr[$k] & 0x3f)); - } - else - { - trigger_error('utf8_from_unicode: Codepoint out of Unicode range at index: '.$k.', value: '.$arr[$k], E_USER_WARNING); - - // Out of range - return false; - } - } - - $result = ob_get_contents(); - ob_end_clean(); - - return $result; -} diff --git a/upload/include/utf8/utils/validation.php b/upload/include/utf8/utils/validation.php deleted file mode 100644 index 90dce8e..0000000 --- a/upload/include/utf8/utils/validation.php +++ /dev/null @@ -1,186 +0,0 @@ - -* @param string UTF-8 encoded string -* @return boolean true if valid -* @see http://hsivonen.iki.fi/php-utf8/ -* @see utf8_compliant -* @package utf8 -* @subpackage validation -*/ -function utf8_is_valid($str) -{ - $mState = 0; // Cached expected number of octets after the current octet - // until the beginning of the next UTF8 character sequence - $mUcs4 = 0; // Cached Unicode character - $mBytes = 1; // Cached expected number of octets in the current sequence - - $len = strlen($str); - - for($i = 0; $i < $len; $i++) - { - $in = ord($str{$i}); - - if ( $mState == 0) - { - // When mState is zero we expect either a US-ASCII character or a multi-octet sequence. - if (0 == (0x80 & ($in))) - { - $mBytes = 1; // US-ASCII, pass straight through - } - else if (0xC0 == (0xE0 & ($in))) - { - // First octet of 2 octet sequence - $mUcs4 = ($in); - $mUcs4 = ($mUcs4 & 0x1F) << 6; - $mState = 1; - $mBytes = 2; - } - else if (0xE0 == (0xF0 & ($in))) - { - // First octet of 3 octet sequence - $mUcs4 = ($in); - $mUcs4 = ($mUcs4 & 0x0F) << 12; - $mState = 2; - $mBytes = 3; - } - else if (0xF0 == (0xF8 & ($in))) - { - // First octet of 4 octet sequence - $mUcs4 = ($in); - $mUcs4 = ($mUcs4 & 0x07) << 18; - $mState = 3; - $mBytes = 4; - } - else if (0xF8 == (0xFC & ($in))) - { - /* First octet of 5 octet sequence. - * - * This is illegal because the encoded codepoint must be either - * (a) not the shortest form or - * (b) outside the Unicode range of 0-0x10FFFF. - * Rather than trying to resynchronize, we will carry on until the end - * of the sequence and let the later error handling code catch it. - */ - $mUcs4 = ($in); - $mUcs4 = ($mUcs4 & 0x03) << 24; - $mState = 4; - $mBytes = 5; - } - else if (0xFC == (0xFE & ($in))) - { - // First octet of 6 octet sequence, see comments for 5 octet sequence. - $mUcs4 = ($in); - $mUcs4 = ($mUcs4 & 1) << 30; - $mState = 5; - $mBytes = 6; - } - else - { - // Current octet is neither in the US-ASCII range nor a legal first octet of a multi-octet sequence. - return false; - } - } - else - { - // When mState is non-zero, we expect a continuation of the multi-octet sequence - if (0x80 == (0xC0 & ($in))) - { - // Legal continuation. - $shift = ($mState - 1) * 6; - $tmp = $in; - $tmp = ($tmp & 0x0000003F) << $shift; - $mUcs4 |= $tmp; - - /** - * End of the multi-octet sequence. mUcs4 now contains the final - * Unicode codepoint to be output - */ - if (0 == --$mState) - { - /* - * Check for illegal sequences and codepoints. - */ - // From Unicode 3.1, non-shortest form is illegal - if (((2 == $mBytes) && ($mUcs4 < 0x0080)) || ((3 == $mBytes) && ($mUcs4 < 0x0800)) || - ((4 == $mBytes) && ($mUcs4 < 0x10000)) || (4 < $mBytes) || - // From Unicode 3.2, surrogate characters are illegal - (($mUcs4 & 0xFFFFF800) == 0xD800) || - // Codepoints outside the Unicode range are illegal - ($mUcs4 > 0x10FFFF)) - { - return FALSE; - } - - // Initialize UTF8 cache - $mState = 0; - $mUcs4 = 0; - $mBytes = 1; - } - } - else - { - /** - *((0xC0 & (*in) != 0x80) && (mState != 0)) - * Incomplete multi-octet sequence. - */ - - return false; - } - } - } - - return true; -} - -/** -* Tests whether a string complies as UTF-8. This will be much -* faster than utf8_is_valid, but will pass five and six octet -* UTF-8 sequences, which are not supported by Unicode and -* so cannot be displayed correctly in a browser. In other words -* it is not as strict as utf8_is_valid but it's faster. If you use -* is to validate user input, you place yourself at the risk that -* attackers will be able to inject 5 and 6 byte sequences (which -* may or may not be a significant risk, depending on what you are -* are doing) -* Note: Does not pass five and six octet UTF-8 sequences anymore in -* in the unit tests. -* @see utf8_is_valid -* @see http://www.php.net/manual/en/reference.pcre.pattern.modifiers.php#54805 -* @param string UTF-8 string to check -* @return boolean TRUE if string is valid UTF-8 -* @package utf8 -* @subpackage validation -*/ -function utf8_compliant($str) -{ - if (strlen($str) == 0) - return true; - - // If even just the first character can be matched, when the /u - // modifier is used, then it's valid UTF-8. If the UTF-8 is somehow - // invalid, nothing at all will match, even if the string contains - // some valid sequences - return (preg_match('/^.{1}/us', $str, $ar) == 1); -} diff --git a/upload/index.php b/upload/index.php deleted file mode 100644 index 5e71bdd..0000000 --- a/upload/index.php +++ /dev/null @@ -1,241 +0,0 @@ -query('SELECT t.forum_id, t.id, t.last_post FROM '.$db->prefix.'topics AS t INNER JOIN '.$db->prefix.'forums AS f ON f.id=t.forum_id LEFT JOIN '.$db->prefix.'forum_perms AS fp ON (fp.forum_id=f.id AND fp.group_id='.$pun_user['g_id'].') WHERE (fp.read_forum IS NULL OR fp.read_forum=1) AND t.last_post>'.$pun_user['last_visit'].' AND t.moved_to IS NULL') or error('Unable to fetch new topics', __FILE__, __LINE__, $db->error()); - - $new_topics = array(); - while ($cur_topic = $db->fetch_assoc($result)) - $new_topics[$cur_topic['forum_id']][$cur_topic['id']] = $cur_topic['last_post']; - - $tracked_topics = get_tracked_topics(); -} - -if ($pun_config['o_feed_type'] == '1') - $page_head = array('feed' => ''); -else if ($pun_config['o_feed_type'] == '2') - $page_head = array('feed' => ''); - -$page_title = array(pun_htmlspecialchars($pun_config['o_board_title'])); -define('PUN_ALLOW_INDEX', 1); -define('PUN_ACTIVE_PAGE', 'index'); -require PUN_ROOT.'header.php'; - -// Print the categories and forums -$result = $db->query('SELECT c.id AS cid, c.cat_name, f.id AS fid, f.forum_name, f.forum_desc, f.redirect_url, f.moderators, f.num_topics, f.num_posts, f.last_post, f.last_post_id, f.last_poster FROM '.$db->prefix.'categories AS c INNER JOIN '.$db->prefix.'forums AS f ON c.id=f.cat_id LEFT JOIN '.$db->prefix.'forum_perms AS fp ON (fp.forum_id=f.id AND fp.group_id='.$pun_user['g_id'].') WHERE fp.read_forum IS NULL OR fp.read_forum=1 ORDER BY c.disp_position, c.id, f.disp_position', true) or error('Unable to fetch category/forum list', __FILE__, __LINE__, $db->error()); - -$cur_category = 0; -$cat_count = 0; -$forum_count = 0; -while ($cur_forum = $db->fetch_assoc($result)) -{ - $moderators = ''; - - if ($cur_forum['cid'] != $cur_category) // A new category since last iteration? - { - if ($cur_category != 0) - echo "\t\t\t".''."\n\t\t\t".''."\n\t\t".'
    '."\n\t".'
    '."\n".'
    '."\n\n"; - - ++$cat_count; - $forum_count = 0; - -?> -
    -

    -
    -
    - - - - - - - - - - - $pun_user['last_visit'] && (empty($tracked_topics['forums'][$cur_forum['fid']]) || $cur_forum['last_post'] > $tracked_topics['forums'][$cur_forum['fid']])) - { - // There are new posts in this forum, but have we read all of them already? - foreach ($new_topics[$cur_forum['fid']] as $check_topic_id => $check_last_post) - { - if ((empty($tracked_topics['topics'][$check_topic_id]) || $tracked_topics['topics'][$check_topic_id] < $check_last_post) && (empty($tracked_topics['forums'][$cur_forum['fid']]) || $tracked_topics['forums'][$cur_forum['fid']] < $check_last_post)) - { - $item_status .= ' inew'; - $forum_field_new = '[ '.$lang_common['New posts'].' ]'; - $icon_type = 'icon icon-new'; - - break; - } - } - } - - // Is this a redirect forum? - if ($cur_forum['redirect_url'] != '') - { - $forum_field = '

    '.$lang_index['Link to'].' '.pun_htmlspecialchars($cur_forum['forum_name']).'

    '; - $num_topics = $num_posts = '-'; - $item_status .= ' iredirect'; - $icon_type = 'icon'; - } - else - { - $forum_field = '

    '.pun_htmlspecialchars($cur_forum['forum_name']).''.(!empty($forum_field_new) ? ' '.$forum_field_new : '').'

    '; - $num_topics = $cur_forum['num_topics']; - $num_posts = $cur_forum['num_posts']; - } - - if ($cur_forum['forum_desc'] != '') - $forum_field .= "\n\t\t\t\t\t\t\t\t".'
    '.$cur_forum['forum_desc'].'
    '; - - // If there is a last_post/last_poster - if ($cur_forum['last_post'] != '') - $last_post = ''.format_time($cur_forum['last_post']).''.$lang_common['by'].' '.pun_htmlspecialchars($cur_forum['last_poster']).''; - else if ($cur_forum['redirect_url'] != '') - $last_post = '- - -'; - else - $last_post = $lang_common['Never']; - - if ($cur_forum['moderators'] != '') - { - $mods_array = unserialize($cur_forum['moderators']); - $moderators = array(); - - foreach ($mods_array as $mod_username => $mod_id) - { - if ($pun_user['g_view_users'] == '1') - $moderators[] = ''.pun_htmlspecialchars($mod_username).''; - else - $moderators[] = pun_htmlspecialchars($mod_username); - } - - $moderators = "\t\t\t\t\t\t\t\t".'

    ('.$lang_common['Moderated by'].' '.implode(', ', $moderators).')

    '."\n"; - } - -?> - - - - - - - 0) - echo "\t\t\t".''."\n\t\t\t".'
    -
    -
    -
    - -
    -
    -
    '."\n\t\t".'
    '."\n\t".'
    '."\n".'
    '."\n\n"; -else - echo '

    '.$lang_index['Empty board'].'

    '; - - -// Collect some statistics from the database -$result = $db->query('SELECT COUNT(id)-1 FROM '.$db->prefix.'users WHERE group_id!='.PUN_UNVERIFIED) or error('Unable to fetch total user count', __FILE__, __LINE__, $db->error()); -$stats['total_users'] = $db->result($result); - -$result = $db->query('SELECT id, username FROM '.$db->prefix.'users WHERE group_id!='.PUN_UNVERIFIED.' ORDER BY registered DESC LIMIT 1') or error('Unable to fetch newest registered user', __FILE__, __LINE__, $db->error()); -$stats['last_user'] = $db->fetch_assoc($result); - -$result = $db->query('SELECT SUM(num_topics), SUM(num_posts) FROM '.$db->prefix.'forums') or error('Unable to fetch topic/post count', __FILE__, __LINE__, $db->error()); -list($stats['total_topics'], $stats['total_posts']) = $db->fetch_row($result); - -if ($pun_user['g_view_users'] == '1') - $stats['newest_user'] = ''.pun_htmlspecialchars($stats['last_user']['username']).''; -else - $stats['newest_user'] = pun_htmlspecialchars($stats['last_user']['username']); - -?> -
    -

    -
    -
    -
    -
    -
    '.forum_number_format($stats['total_users']).'') ?>
    -
    '.forum_number_format($stats['total_topics']).'') ?>
    -
    '.forum_number_format($stats['total_posts']).'') ?>
    -
    -
    -
    -
    -query('SELECT user_id, ident FROM '.$db->prefix.'online WHERE idle=0 ORDER BY ident', true) or error('Unable to fetch online list', __FILE__, __LINE__, $db->error()); - - while ($pun_user_online = $db->fetch_assoc($result)) - { - if ($pun_user_online['user_id'] > 1) - { - if ($pun_user['g_view_users'] == '1') - $users[] = "\n\t\t\t\t".'
    '.pun_htmlspecialchars($pun_user_online['ident']).''; - else - $users[] = "\n\t\t\t\t".'
    '.pun_htmlspecialchars($pun_user_online['ident']); - } - else - ++$num_guests; - } - - $num_users = count($users); - echo "\t\t\t\t".'
    '.sprintf($lang_index['Users online'], ''.forum_number_format($num_users).'').'
    '."\n\t\t\t\t".'
    '.sprintf($lang_index['Guests online'], ''.forum_number_format($num_guests).'').'
    '."\n\t\t\t".'
    '."\n"; - - - if ($num_users > 0) - echo "\t\t\t".'
    '."\n\t\t\t\t".'
    '.$lang_index['Online'].'
    '."\t\t\t\t".implode(', ', $users).''."\n\t\t\t".'
    '."\n"; - else - echo "\t\t\t".'
    '."\n"; - -} -else - echo "\t\t\t".''."\n\t\t\t".'
    '."\n"; - - -?> -
    -
    -
    -here instead.'); -} - -// Define PUN because email.php requires it -define('PUN', 1); - -// Make sure we are running at least MIN_PHP_VERSION -if (!function_exists('version_compare') || version_compare(PHP_VERSION, MIN_PHP_VERSION, '<')) - exit('You are running PHP version '.PHP_VERSION.'. FluxBB '.FORUM_VERSION.' requires at least PHP '.MIN_PHP_VERSION.' to run properly. You must upgrade your PHP installation before you can continue.'); - -// Load the functions script -require PUN_ROOT.'include/functions.php'; - -// Load UTF-8 functions -require PUN_ROOT.'include/utf8/utf8.php'; - -// Strip out "bad" UTF-8 characters -forum_remove_bad_characters(); - -// Reverse the effect of register_globals -forum_unregister_globals(); - -// Disable error reporting for uninitialized variables -error_reporting(E_ALL); - -// Force POSIX locale (to prevent functions such as strtolower() from messing up UTF-8 strings) -setlocale(LC_CTYPE, 'C'); - -// Turn off magic_quotes_runtime -if (get_magic_quotes_runtime()) - set_magic_quotes_runtime(0); - -// Strip slashes from GET/POST/COOKIE (if magic_quotes_gpc is enabled) -if (get_magic_quotes_gpc()) -{ - function stripslashes_array($array) - { - return is_array($array) ? array_map('stripslashes_array', $array) : stripslashes($array); - } - - $_GET = stripslashes_array($_GET); - $_POST = stripslashes_array($_POST); - $_COOKIE = stripslashes_array($_COOKIE); - $_REQUEST = stripslashes_array($_REQUEST); -} - -// Turn off PHP time limit -@set_time_limit(0); - -// -// Generate output to be used for config.php -// -function generate_config_file() -{ - global $db_type, $db_host, $db_name, $db_username, $db_password, $db_prefix, $cookie_name, $cookie_seed; - - return ' 2) - $dual_mysql = true; - } - if (function_exists('sqlite_open')) - $db_extensions[] = array('sqlite', 'SQLite'); - if (function_exists('pg_connect')) - $db_extensions[] = array('pgsql', 'PostgreSQL'); - - if (empty($db_extensions)) - exit('This PHP environment does not have support for any of the databases that FluxBB supports. PHP needs to have support for either MySQL, PostgreSQL or SQLite in order for FluxBB to be installed.'); - - // Make an educated guess regarding base_url - $base_url = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') ? 'https://' : 'http://'; // protocol - $base_url .= preg_replace('/:(80|443)$/', '', $_SERVER['HTTP_HOST']); // host[:port] - $base_url .= str_replace('\\', '/', dirname($_SERVER['SCRIPT_NAME'])); // path - - if (substr($base_url, -1) == '/') - $base_url = substr($base_url, 0, -1); - - $title = 'My FluxBB forum'; - $description = '

    Unfortunately no one can be told what FluxBB is - you have to see it for yourself.

    '; - $default_lang = 'English'; - $default_style = 'Air'; - -?> - - - - - -FluxBB Installation - - - - - - -
    -
    - -
    - -
    -
    -
    -

    FluxBB Installation

    -

    Welcome to FluxBB installation. You are about to install FluxBB. In order to install FluxBB, you must complete the form set out below. If you encounter any difficulties with the installation, please refer to the documentation.

    -
    -
    -
    - -
    -
    -

    Install FluxBB 1.4

    -
    -
    -
    -
    -
    -

    Database setup

    -

    Please enter the requested information in order to setup your database for FluxBB. You must know all the information asked for before proceeding with the installation.

    -
    -
    - Select your database type -
    -

    FluxBB currently supports MySQL, PostgreSQL and SQLite. If your database of choice is missing from the drop-down menu below, it means this PHP environment does not have support for that particular database. More information regarding support for particular versions of each database can be found in the FAQ.

    -

    FluxBB has detected that your PHP environment supports two different ways of communicating with MySQL. The two options are called standard and improved. If you are uncertain which one to use, start by trying improved and if that fails, try standard.

    -

    FluxBB has detected that your MySQL server might support InnoDB. This would be a good choice if you are planning to run a large forum. If you are uncertain, it is recommended that you do not use InnoDB.

    - -
    -
    -
    -
    -
    - Enter your database server hostname -
    -

    The address of the database server (example: localhost, db.myhost.com or 192.168.0.15). You can specify a custom port number if your database doesn't run on the default port (example: localhost:3580). For SQLite support, just enter anything or leave it at 'localhost'.

    - -
    -
    -
    -
    -
    - Enter the name of your database -
    -

    The name of the database that FluxBB will be installed into. The database must exist. For SQLite, this is the relative path to the database file. If the SQLite database file does not exist, FluxBB will attempt to create it.

    - -
    -
    -
    -
    -
    - Enter your database username and password -
    -

    Enter the username and password with which you connect to the database. Ignore for SQLite.

    - - -
    -
    -
    -
    -
    -
    - Enter database table prefix -
    -

    If you like, you can specify a table prefix. This way you can run multiple copies of FluxBB in the same database (example: foo_).

    - -
    -
    -
    -
    -
    -

    Administration setup

    -

    Please enter the requested information in order to setup an administrator for your FluxBB installation.

    -
    -
    - Enter Administrator's username -
    -

    The username of the forum administrator. You can later create more administrators and moderators. Usernames can be between 2 and 25 characters long.

    - -
    -
    -
    -
    -
    - Enter and confirm Administrator's password -
    -

    Passwords must be at least 4 characters long. Passwords are case sensitive.

    - - -
    -
    -
    -
    -
    -
    - Enter Administrator's email -
    -

    The email address of the forum administrator.

    - -
    -
    -
    -
    -
    -

    Board setup

    -

    Please enter the requested information in order to setup your FluxBB board.

    -
    -
    - Enter your board's title -
    -

    The title of this bulletin board (shown at the top of every page).

    - -
    -
    -
    -
    -
    - Enter your board's description -
    -

    A short description of this bulletin board (shown at the top of every page). This field may contain HTML.

    - -
    -
    -
    -
    -
    - Enter the Base URL of your FluxBB installation -
    -

    The URL (without trailing slash) of your FluxBB forum (example: http://forum.myhost.com or http://myhost.com/~myuser). This must be correct, otherwise, administrators and moderators will not be able to submit any forms. Please note that the preset value below is just an educated guess by FluxBB.

    - -
    -
    -
    -
    -
    - Choose the default language -
    -

    The default language used for guests and users who haven't changed from the default in their profile.

    - -
    -
    -
    -
    -
    - Choose the default style -
    -

    The default style used for guests and users who haven't changed from the default in their profile.

    - -
    -
    -
    -

    -
    -
    -
    -
    - -
    - -
    -
    - - - - 25) // This usually doesn't happen since the form element only accepts 25 characters - error('Usernames must not be more than 25 characters long. Please go back and correct'); - else if (!strcasecmp($username, 'Guest')) - error('The username guest is reserved. Please go back and correct'); - else if (preg_match('/[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}/', $username) || preg_match('/((([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}:[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){5}:([0-9A-Fa-f]{1,4}:)?[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){4}:([0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){3}:([0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){2}:([0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|(([0-9A-Fa-f]{1,4}:){0,5}:((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|(::([0-9A-Fa-f]{1,4}:){0,5}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|([0-9A-Fa-f]{1,4}::([0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})|(::([0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){1,7}:))/', $username)) - error('Usernames may not be in the form of an IP address. Please go back and correct'); - else if ((strpos($username, '[') !== false || strpos($username, ']') !== false) && strpos($username, '\'') !== false && strpos($username, '"') !== false) - error('Usernames may not contain all the characters \', " and [ or ] at once. Please choose another username'); - else if (preg_match('/(?:\[\/?(?:b|u|i|h|colou?r|quote|code|img|url|email|list)\]|\[(?:code|quote|list)=)/i', $username)) - error('Usernames may not contain any of the text formatting tags (BBCode) that the forum uses. Please go back and correct'); - - if (pun_strlen($password1) < 4) - error('Passwords must be at least 4 characters long. Please go back and correct'); - else if ($password1 != $password2) - error('Passwords do not match. Please go back and correct'); - - // Validate email - require PUN_ROOT.'include/email.php'; - - if (!is_valid_email($email)) - error('The administrator email address you entered is invalid. Please go back and correct'); - - if ($title == '') - error('You must enter a board title.'); - - $default_lang = preg_replace('#[\.\\\/]#', '', $default_lang); - if (!file_exists(PUN_ROOT.'lang/'.$default_lang.'/common.php')) - error('The default language chosen doesn\'t seem to exist. Please go back and correct'); - - $default_style = preg_replace('#[\.\\\/]#', '', $default_style); - if (!file_exists(PUN_ROOT.'style/'.$default_style.'.css')) - error('The default style chosen doesn\'t seem to exist. Please go back and correct'); - - // Load the appropriate DB layer class - switch ($db_type) - { - case 'mysql': - require PUN_ROOT.'include/dblayer/mysql.php'; - break; - - case 'mysql_innodb': - require PUN_ROOT.'include/dblayer/mysql_innodb.php'; - break; - - case 'mysqli': - require PUN_ROOT.'include/dblayer/mysqli.php'; - break; - - case 'mysqli_innodb': - require PUN_ROOT.'include/dblayer/mysqli_innodb.php'; - break; - - case 'pgsql': - require PUN_ROOT.'include/dblayer/pgsql.php'; - break; - - case 'sqlite': - require PUN_ROOT.'include/dblayer/sqlite.php'; - break; - - default: - error('\''.pun_htmlspecialchars($db_type).'\' is not a valid database type'); - } - - // Create the database object (and connect/select db) - $db = new DBLayer($db_host, $db_username, $db_password, $db_name, $db_prefix, false); - - // Validate prefix - if (strlen($db_prefix) > 0 && (!preg_match('/^[a-zA-Z_][a-zA-Z0-9_]*$/', $db_prefix) || strlen($db_prefix) > 40)) - error('The table prefix \''.$db->prefix.'\' contains illegal characters or is too long. The prefix may contain the letters a to z, any numbers and the underscore character. They must however not start with a number. The maximum length is 40 characters. Please choose a different prefix'); - - // Do some DB type specific checks - switch ($db_type) - { - case 'mysql': - case 'mysqli': - case 'mysql_innodb': - case 'mysqli_innodb': - $mysql_info = $db->get_version(); - if (version_compare($mysql_info['version'], MIN_MYSQL_VERSION, '<')) - error('You are running MySQL version '.$mysql_version.'. FluxBB '.FORUM_VERSION.' requires at least MySQL '.MIN_MYSQL_VERSION.' to run properly. You must upgrade your MySQL installation before you can continue'); - break; - - case 'pgsql': - $pgsql_info = $db->get_version(); - if (version_compare($pgsql_info['version'], MIN_PGSQL_VERSION, '<')) - error('You are running PostgreSQL version '.$pgsql_info.'. FluxBB '.FORUM_VERSION.' requires at least PostgreSQL '.MIN_PGSQL_VERSION.' to run properly. You must upgrade your PostgreSQL installation before you can continue'); - break; - - case 'sqlite': - if (strtolower($db_prefix) == 'sqlite_') - error('The table prefix \'sqlite_\' is reserved for use by the SQLite engine. Please choose a different prefix'); - break; - } - - - // Make sure FluxBB isn't already installed - $result = $db->query('SELECT 1 FROM '.$db_prefix.'users WHERE id=1'); - if ($db->num_rows($result)) - error('A table called "'.$db_prefix.'users" is already present in the database "'.$db_name.'". This could mean that FluxBB is already installed or that another piece of software is installed and is occupying one or more of the table names FluxBB requires. If you want to install multiple copies of FluxBB in the same database, you must choose a different table prefix'); - - // Check if InnoDB is available - if ($db_type == 'mysql_innodb' || $db_type == 'mysqli_innodb') - { - $result = $db->query('SHOW VARIABLES LIKE \'have_innodb\''); - list (, $result) = $db->fetch_row($result); - if ((strtoupper($result) != 'YES')) - error('InnoDB does not seem to be enabled. Please choose a database layer that does not have InnoDB support, or enable InnoDB on your MySQL server'); - } - - - // Start a transaction - $db->start_transaction(); - - - // Create all tables - $schema = array( - 'FIELDS' => array( - 'id' => array( - 'datatype' => 'SERIAL', - 'allow_null' => false - ), - 'username' => array( - 'datatype' => 'VARCHAR(200)', - 'allow_null' => true - ), - 'ip' => array( - 'datatype' => 'VARCHAR(255)', - 'allow_null' => true - ), - 'email' => array( - 'datatype' => 'VARCHAR(80)', - 'allow_null' => true - ), - 'message' => array( - 'datatype' => 'VARCHAR(255)', - 'allow_null' => true - ), - 'expire' => array( - 'datatype' => 'INT(10) UNSIGNED', - 'allow_null' => true - ), - 'ban_creator' => array( - 'datatype' => 'INT(10) UNSIGNED', - 'allow_null' => false, - 'default' => '0' - ) - ), - 'PRIMARY KEY' => array('id'), - 'INDEXES' => array( - 'username_idx' => array('username') - ) - ); - - if ($db_type == 'mysql' || $db_type == 'mysqli' || $db_type == 'mysql_innodb' || $db_type == 'mysqli_innodb') - $schema['INDEXES']['username_idx'] = array('username(25)'); - - $db->create_table('bans', $schema) or error('Unable to create bans table', __FILE__, __LINE__, $db->error()); - - - $schema = array( - 'FIELDS' => array( - 'id' => array( - 'datatype' => 'SERIAL', - 'allow_null' => false - ), - 'cat_name' => array( - 'datatype' => 'VARCHAR(80)', - 'allow_null' => false, - 'default' => '\'New Category\'' - ), - 'disp_position' => array( - 'datatype' => 'INT(10)', - 'allow_null' => false, - 'default' => '0' - ) - ), - 'PRIMARY KEY' => array('id') - ); - - $db->create_table('categories', $schema) or error('Unable to create categories table', __FILE__, __LINE__, $db->error()); - - - $schema = array( - 'FIELDS' => array( - 'id' => array( - 'datatype' => 'SERIAL', - 'allow_null' => false - ), - 'search_for' => array( - 'datatype' => 'VARCHAR(60)', - 'allow_null' => false, - 'default' => '\'\'' - ), - 'replace_with' => array( - 'datatype' => 'VARCHAR(60)', - 'allow_null' => false, - 'default' => '\'\'' - ) - ), - 'PRIMARY KEY' => array('id') - ); - - $db->create_table('censoring', $schema) or error('Unable to create censoring table', __FILE__, __LINE__, $db->error()); - - - $schema = array( - 'FIELDS' => array( - 'conf_name' => array( - 'datatype' => 'VARCHAR(255)', - 'allow_null' => false, - 'default' => '\'\'' - ), - 'conf_value' => array( - 'datatype' => 'TEXT', - 'allow_null' => true - ) - ), - 'PRIMARY KEY' => array('conf_name') - ); - - $db->create_table('config', $schema) or error('Unable to create config table', __FILE__, __LINE__, $db->error()); - - - $schema = array( - 'FIELDS' => array( - 'group_id' => array( - 'datatype' => 'INT(10)', - 'allow_null' => false, - 'default' => '0' - ), - 'forum_id' => array( - 'datatype' => 'INT(10)', - 'allow_null' => false, - 'default' => '0' - ), - 'read_forum' => array( - 'datatype' => 'TINYINT(1)', - 'allow_null' => false, - 'default' => '1' - ), - 'post_replies' => array( - 'datatype' => 'TINYINT(1)', - 'allow_null' => false, - 'default' => '1' - ), - 'post_topics' => array( - 'datatype' => 'TINYINT(1)', - 'allow_null' => false, - 'default' => '1' - ) - ), - 'PRIMARY KEY' => array('group_id', 'forum_id') - ); - - $db->create_table('forum_perms', $schema) or error('Unable to create forum_perms table', __FILE__, __LINE__, $db->error()); - - - $schema = array( - 'FIELDS' => array( - 'id' => array( - 'datatype' => 'SERIAL', - 'allow_null' => false - ), - 'forum_name' => array( - 'datatype' => 'VARCHAR(80)', - 'allow_null' => false, - 'default' => '\'New forum\'' - ), - 'forum_desc' => array( - 'datatype' => 'TEXT', - 'allow_null' => true - ), - 'redirect_url' => array( - 'datatype' => 'VARCHAR(100)', - 'allow_null' => true - ), - 'moderators' => array( - 'datatype' => 'TEXT', - 'allow_null' => true - ), - 'num_topics' => array( - 'datatype' => 'MEDIUMINT(8) UNSIGNED', - 'allow_null' => false, - 'default' => '0' - ), - 'num_posts' => array( - 'datatype' => 'MEDIUMINT(8) UNSIGNED', - 'allow_null' => false, - 'default' => '0' - ), - 'last_post' => array( - 'datatype' => 'INT(10) UNSIGNED', - 'allow_null' => true - ), - 'last_post_id' => array( - 'datatype' => 'INT(10) UNSIGNED', - 'allow_null' => true - ), - 'last_poster' => array( - 'datatype' => 'VARCHAR(200)', - 'allow_null' => true - ), - 'sort_by' => array( - 'datatype' => 'TINYINT(1)', - 'allow_null' => false, - 'default' => '0' - ), - 'disp_position' => array( - 'datatype' => 'INT(10)', - 'allow_null' => false, - 'default' => '0' - ), - 'cat_id' => array( - 'datatype' => 'INT(10) UNSIGNED', - 'allow_null' => false, - 'default' => '0' - ) - ), - 'PRIMARY KEY' => array('id') - ); - - $db->create_table('forums', $schema) or error('Unable to create forums table', __FILE__, __LINE__, $db->error()); - - - $schema = array( - 'FIELDS' => array( - 'g_id' => array( - 'datatype' => 'SERIAL', - 'allow_null' => false - ), - 'g_title' => array( - 'datatype' => 'VARCHAR(50)', - 'allow_null' => false, - 'default' => '\'\'' - ), - 'g_user_title' => array( - 'datatype' => 'VARCHAR(50)', - 'allow_null' => true - ), - 'g_moderator' => array( - 'datatype' => 'TINYINT(1)', - 'allow_null' => false, - 'default' => '0' - ), - 'g_mod_edit_users' => array( - 'datatype' => 'TINYINT(1)', - 'allow_null' => false, - 'default' => '0' - ), - 'g_mod_rename_users' => array( - 'datatype' => 'TINYINT(1)', - 'allow_null' => false, - 'default' => '0' - ), - 'g_mod_change_passwords' => array( - 'datatype' => 'TINYINT(1)', - 'allow_null' => false, - 'default' => '0' - ), - 'g_mod_ban_users' => array( - 'datatype' => 'TINYINT(1)', - 'allow_null' => false, - 'default' => '0' - ), - 'g_read_board' => array( - 'datatype' => 'TINYINT(1)', - 'allow_null' => false, - 'default' => '1' - ), - 'g_view_users' => array( - 'datatype' => 'TINYINT(1)', - 'allow_null' => false, - 'default' => '1' - ), - 'g_post_replies' => array( - 'datatype' => 'TINYINT(1)', - 'allow_null' => false, - 'default' => '1' - ), - 'g_post_topics' => array( - 'datatype' => 'TINYINT(1)', - 'allow_null' => false, - 'default' => '1' - ), - 'g_edit_posts' => array( - 'datatype' => 'TINYINT(1)', - 'allow_null' => false, - 'default' => '1' - ), - 'g_delete_posts' => array( - 'datatype' => 'TINYINT(1)', - 'allow_null' => false, - 'default' => '1' - ), - 'g_delete_topics' => array( - 'datatype' => 'TINYINT(1)', - 'allow_null' => false, - 'default' => '1' - ), - 'g_set_title' => array( - 'datatype' => 'TINYINT(1)', - 'allow_null' => false, - 'default' => '1' - ), - 'g_search' => array( - 'datatype' => 'TINYINT(1)', - 'allow_null' => false, - 'default' => '1' - ), - 'g_search_users' => array( - 'datatype' => 'TINYINT(1)', - 'allow_null' => false, - 'default' => '1' - ), - 'g_send_email' => array( - 'datatype' => 'TINYINT(1)', - 'allow_null' => false, - 'default' => '1' - ), - 'g_post_flood' => array( - 'datatype' => 'SMALLINT(6)', - 'allow_null' => false, - 'default' => '30' - ), - 'g_search_flood' => array( - 'datatype' => 'SMALLINT(6)', - 'allow_null' => false, - 'default' => '30' - ), - 'g_email_flood' => array( - 'datatype' => 'SMALLINT(6)', - 'allow_null' => false, - 'default' => '60' - ) - ), - 'PRIMARY KEY' => array('g_id') - ); - - $db->create_table('groups', $schema) or error('Unable to create groups table', __FILE__, __LINE__, $db->error()); - - - $schema = array( - 'FIELDS' => array( - 'user_id' => array( - 'datatype' => 'INT(10) UNSIGNED', - 'allow_null' => false, - 'default' => '1' - ), - 'ident' => array( - 'datatype' => 'VARCHAR(200)', - 'allow_null' => false, - 'default' => '\'\'' - ), - 'logged' => array( - 'datatype' => 'INT(10) UNSIGNED', - 'allow_null' => false, - 'default' => '0' - ), - 'idle' => array( - 'datatype' => 'TINYINT(1)', - 'allow_null' => false, - 'default' => '0' - ), - 'last_post' => array( - 'datatype' => 'INT(10) UNSIGNED', - 'allow_null' => true - ), - 'last_search' => array( - 'datatype' => 'INT(10) UNSIGNED', - 'allow_null' => true - ), - ), - 'UNIQUE KEYS' => array( - 'user_id_ident_idx' => array('user_id', 'ident') - ), - 'INDEXES' => array( - 'ident_idx' => array('ident'), - 'logged_idx' => array('logged') - ), - 'ENGINE' => 'HEAP' - ); - - if ($db_type == 'mysql' || $db_type == 'mysqli' || $db_type == 'mysql_innodb' || $db_type == 'mysqli_innodb') - { - $schema['UNIQUE KEYS']['user_id_ident_idx'] = array('user_id', 'ident(25)'); - $schema['INDEXES']['ident_idx'] = array('ident(25)'); - } - - if ($db_type == 'mysql_innodb' || $db_type == 'mysqli_innodb') - $schema['ENGINE'] = 'InnoDB'; - - $db->create_table('online', $schema) or error('Unable to create online table', __FILE__, __LINE__, $db->error()); - - - $schema = array( - 'FIELDS' => array( - 'id' => array( - 'datatype' => 'SERIAL', - 'allow_null' => false - ), - 'poster' => array( - 'datatype' => 'VARCHAR(200)', - 'allow_null' => false, - 'default' => '\'\'' - ), - 'poster_id' => array( - 'datatype' => 'INT(10) UNSIGNED', - 'allow_null' => false, - 'default' => '1' - ), - 'poster_ip' => array( - 'datatype' => 'VARCHAR(39)', - 'allow_null' => true - ), - 'poster_email' => array( - 'datatype' => 'VARCHAR(80)', - 'allow_null' => true - ), - 'message' => array( - 'datatype' => 'TEXT', - 'allow_null' => true - ), - 'hide_smilies' => array( - 'datatype' => 'TINYINT(1)', - 'allow_null' => false, - 'default' => '0' - ), - 'posted' => array( - 'datatype' => 'INT(10) UNSIGNED', - 'allow_null' => false, - 'default' => '0' - ), - 'edited' => array( - 'datatype' => 'INT(10) UNSIGNED', - 'allow_null' => true - ), - 'edited_by' => array( - 'datatype' => 'VARCHAR(200)', - 'allow_null' => true - ), - 'topic_id' => array( - 'datatype' => 'INT(10) UNSIGNED', - 'allow_null' => false, - 'default' => '0' - ) - ), - 'PRIMARY KEY' => array('id'), - 'INDEXES' => array( - 'topic_id_idx' => array('topic_id'), - 'multi_idx' => array('poster_id', 'topic_id') - ) - ); - - $db->create_table('posts', $schema) or error('Unable to create posts table', __FILE__, __LINE__, $db->error()); - - - $schema = array( - 'FIELDS' => array( - 'id' => array( - 'datatype' => 'SERIAL', - 'allow_null' => false - ), - 'rank' => array( - 'datatype' => 'VARCHAR(50)', - 'allow_null' => false, - 'default' => '\'\'' - ), - 'min_posts' => array( - 'datatype' => 'MEDIUMINT(8) UNSIGNED', - 'allow_null' => false, - 'default' => '0' - ) - ), - 'PRIMARY KEY' => array('id') - ); - - $db->create_table('ranks', $schema) or error('Unable to create ranks table', __FILE__, __LINE__, $db->error()); - - - $schema = array( - 'FIELDS' => array( - 'id' => array( - 'datatype' => 'SERIAL', - 'allow_null' => false - ), - 'post_id' => array( - 'datatype' => 'INT(10) UNSIGNED', - 'allow_null' => false, - 'default' => '0' - ), - 'topic_id' => array( - 'datatype' => 'INT(10) UNSIGNED', - 'allow_null' => false, - 'default' => '0' - ), - 'forum_id' => array( - 'datatype' => 'INT(10) UNSIGNED', - 'allow_null' => false, - 'default' => '0' - ), - 'reported_by' => array( - 'datatype' => 'INT(10) UNSIGNED', - 'allow_null' => false, - 'default' => '0' - ), - 'created' => array( - 'datatype' => 'INT(10) UNSIGNED', - 'allow_null' => false, - 'default' => '0' - ), - 'message' => array( - 'datatype' => 'TEXT', - 'allow_null' => true - ), - 'zapped' => array( - 'datatype' => 'INT(10) UNSIGNED', - 'allow_null' => true - ), - 'zapped_by' => array( - 'datatype' => 'INT(10) UNSIGNED', - 'allow_null' => true - ) - ), - 'PRIMARY KEY' => array('id'), - 'INDEXES' => array( - 'zapped_idx' => array('zapped') - ) - ); - - $db->create_table('reports', $schema) or error('Unable to create reports table', __FILE__, __LINE__, $db->error()); - - - $schema = array( - 'FIELDS' => array( - 'id' => array( - 'datatype' => 'INT(10) UNSIGNED', - 'allow_null' => false, - 'default' => '0' - ), - 'ident' => array( - 'datatype' => 'VARCHAR(200)', - 'allow_null' => false, - 'default' => '\'\'' - ), - 'search_data' => array( - 'datatype' => 'MEDIUMTEXT', - 'allow_null' => true - ) - ), - 'PRIMARY KEY' => array('id'), - 'INDEXES' => array( - 'ident_idx' => array('ident') - ) - ); - - if ($db_type == 'mysql' || $db_type == 'mysqli' || $db_type == 'mysql_innodb' || $db_type == 'mysqli_innodb') - $schema['INDEXES']['ident_idx'] = array('ident(8)'); - - $db->create_table('search_cache', $schema) or error('Unable to create search_cache table', __FILE__, __LINE__, $db->error()); - - - $schema = array( - 'FIELDS' => array( - 'post_id' => array( - 'datatype' => 'INT(10) UNSIGNED', - 'allow_null' => false, - 'default' => '0' - ), - 'word_id' => array( - 'datatype' => 'INT(10) UNSIGNED', - 'allow_null' => false, - 'default' => '0' - ), - 'subject_match' => array( - 'datatype' => 'TINYINT(1)', - 'allow_null' => false, - 'default' => '0' - ) - ), - 'INDEXES' => array( - 'word_id_idx' => array('word_id'), - 'post_id_idx' => array('post_id') - ) - ); - - $db->create_table('search_matches', $schema) or error('Unable to create search_matches table', __FILE__, __LINE__, $db->error()); - - - $schema = array( - 'FIELDS' => array( - 'id' => array( - 'datatype' => 'SERIAL', - 'allow_null' => false - ), - 'word' => array( - 'datatype' => 'VARCHAR(20)', - 'allow_null' => false, - 'default' => '\'\'', - 'collation' => 'bin' - ) - ), - 'PRIMARY KEY' => array('word'), - 'INDEXES' => array( - 'id_idx' => array('id') - ) - ); - - if ($db_type == 'sqlite') - { - $schema['PRIMARY KEY'] = array('id'); - $schema['UNIQUE KEYS'] = array('word_idx' => array('word')); - } - - $db->create_table('search_words', $schema) or error('Unable to create search_words table', __FILE__, __LINE__, $db->error()); - - - $schema = array( - 'FIELDS' => array( - 'user_id' => array( - 'datatype' => 'INT(10) UNSIGNED', - 'allow_null' => false, - 'default' => '0' - ), - 'topic_id' => array( - 'datatype' => 'INT(10) UNSIGNED', - 'allow_null' => false, - 'default' => '0' - ) - ), - 'PRIMARY KEY' => array('user_id', 'topic_id') - ); - - $db->create_table('subscriptions', $schema) or error('Unable to create subscriptions table', __FILE__, __LINE__, $db->error()); - - - $schema = array( - 'FIELDS' => array( - 'id' => array( - 'datatype' => 'SERIAL', - 'allow_null' => false - ), - 'poster' => array( - 'datatype' => 'VARCHAR(200)', - 'allow_null' => false, - 'default' => '\'\'' - ), - 'subject' => array( - 'datatype' => 'VARCHAR(255)', - 'allow_null' => false, - 'default' => '\'\'' - ), - 'posted' => array( - 'datatype' => 'INT(10) UNSIGNED', - 'allow_null' => false, - 'default' => '0' - ), - 'first_post_id' => array( - 'datatype' => 'INT(10) UNSIGNED', - 'allow_null' => false, - 'default' => '0' - ), - 'last_post' => array( - 'datatype' => 'INT(10) UNSIGNED', - 'allow_null' => false, - 'default' => '0' - ), - 'last_post_id' => array( - 'datatype' => 'INT(10) UNSIGNED', - 'allow_null' => false, - 'default' => '0' - ), - 'last_poster' => array( - 'datatype' => 'VARCHAR(200)', - 'allow_null' => true - ), - 'num_views' => array( - 'datatype' => 'MEDIUMINT(8) UNSIGNED', - 'allow_null' => false, - 'default' => '0' - ), - 'num_replies' => array( - 'datatype' => 'MEDIUMINT(8) UNSIGNED', - 'allow_null' => false, - 'default' => '0' - ), - 'closed' => array( - 'datatype' => 'TINYINT(1)', - 'allow_null' => false, - 'default' => '0' - ), - 'sticky' => array( - 'datatype' => 'TINYINT(1)', - 'allow_null' => false, - 'default' => '0' - ), - 'moved_to' => array( - 'datatype' => 'INT(10) UNSIGNED', - 'allow_null' => true - ), - 'forum_id' => array( - 'datatype' => 'INT(10) UNSIGNED', - 'allow_null' => false, - 'default' => '0' - ) - ), - 'PRIMARY KEY' => array('id'), - 'INDEXES' => array( - 'forum_id_idx' => array('forum_id'), - 'moved_to_idx' => array('moved_to'), - 'last_post_idx' => array('last_post'), - 'first_post_id_idx' => array('first_post_id') - ) - ); - - $db->create_table('topics', $schema) or error('Unable to create topics table', __FILE__, __LINE__, $db->error()); - - - $schema = array( - 'FIELDS' => array( - 'id' => array( - 'datatype' => 'SERIAL', - 'allow_null' => false - ), - 'group_id' => array( - 'datatype' => 'INT(10) UNSIGNED', - 'allow_null' => false, - 'default' => '3' - ), - 'username' => array( - 'datatype' => 'VARCHAR(200)', - 'allow_null' => false, - 'default' => '\'\'' - ), - 'password' => array( - 'datatype' => 'VARCHAR(40)', - 'allow_null' => false, - 'default' => '\'\'' - ), - 'email' => array( - 'datatype' => 'VARCHAR(80)', - 'allow_null' => false, - 'default' => '\'\'' - ), - 'title' => array( - 'datatype' => 'VARCHAR(50)', - 'allow_null' => true - ), - 'realname' => array( - 'datatype' => 'VARCHAR(40)', - 'allow_null' => true - ), - 'url' => array( - 'datatype' => 'VARCHAR(100)', - 'allow_null' => true - ), - 'jabber' => array( - 'datatype' => 'VARCHAR(80)', - 'allow_null' => true - ), - 'icq' => array( - 'datatype' => 'VARCHAR(12)', - 'allow_null' => true - ), - 'msn' => array( - 'datatype' => 'VARCHAR(80)', - 'allow_null' => true - ), - 'aim' => array( - 'datatype' => 'VARCHAR(30)', - 'allow_null' => true - ), - 'yahoo' => array( - 'datatype' => 'VARCHAR(30)', - 'allow_null' => true - ), - 'location' => array( - 'datatype' => 'VARCHAR(30)', - 'allow_null' => true - ), - 'signature' => array( - 'datatype' => 'TEXT', - 'allow_null' => true - ), - 'disp_topics' => array( - 'datatype' => 'TINYINT(3) UNSIGNED', - 'allow_null' => true - ), - 'disp_posts' => array( - 'datatype' => 'TINYINT(3) UNSIGNED', - 'allow_null' => true - ), - 'email_setting' => array( - 'datatype' => 'TINYINT(1)', - 'allow_null' => false, - 'default' => '1' - ), - 'notify_with_post' => array( - 'datatype' => 'TINYINT(1)', - 'allow_null' => false, - 'default' => '0' - ), - 'auto_notify' => array( - 'datatype' => 'TINYINT(1)', - 'allow_null' => false, - 'default' => '0' - ), - 'show_smilies' => array( - 'datatype' => 'TINYINT(1)', - 'allow_null' => false, - 'default' => '1' - ), - 'show_img' => array( - 'datatype' => 'TINYINT(1)', - 'allow_null' => false, - 'default' => '1' - ), - 'show_img_sig' => array( - 'datatype' => 'TINYINT(1)', - 'allow_null' => false, - 'default' => '1' - ), - 'show_avatars' => array( - 'datatype' => 'TINYINT(1)', - 'allow_null' => false, - 'default' => '1' - ), - 'show_sig' => array( - 'datatype' => 'TINYINT(1)', - 'allow_null' => false, - 'default' => '1' - ), - 'timezone' => array( - 'datatype' => 'FLOAT', - 'allow_null' => false, - 'default' => '0' - ), - 'dst' => array( - 'datatype' => 'TINYINT(1)', - 'allow_null' => false, - 'default' => '0' - ), - 'time_format' => array( - 'datatype' => 'TINYINT(1)', - 'allow_null' => false, - 'default' => '0' - ), - 'date_format' => array( - 'datatype' => 'TINYINT(1)', - 'allow_null' => false, - 'default' => '0' - ), - 'language' => array( - 'datatype' => 'VARCHAR(25)', - 'allow_null' => false, - 'default' => '\'English\'' - ), - 'style' => array( - 'datatype' => 'VARCHAR(25)', - 'allow_null' => false, - 'default' => '\''.$db->escape($default_style).'\'' - ), - 'num_posts' => array( - 'datatype' => 'INT(10) UNSIGNED', - 'allow_null' => false, - 'default' => '0' - ), - 'last_post' => array( - 'datatype' => 'INT(10) UNSIGNED', - 'allow_null' => true - ), - 'last_search' => array( - 'datatype' => 'INT(10) UNSIGNED', - 'allow_null' => true - ), - 'last_email_sent' => array( - 'datatype' => 'INT(10) UNSIGNED', - 'allow_null' => true - ), - 'registered' => array( - 'datatype' => 'INT(10) UNSIGNED', - 'allow_null' => false, - 'default' => '0' - ), - 'registration_ip' => array( - 'datatype' => 'VARCHAR(39)', - 'allow_null' => false, - 'default' => '\'0.0.0.0\'' - ), - 'last_visit' => array( - 'datatype' => 'INT(10) UNSIGNED', - 'allow_null' => false, - 'default' => '0' - ), - 'admin_note' => array( - 'datatype' => 'VARCHAR(30)', - 'allow_null' => true - ), - 'activate_string' => array( - 'datatype' => 'VARCHAR(80)', - 'allow_null' => true - ), - 'activate_key' => array( - 'datatype' => 'VARCHAR(8)', - 'allow_null' => true - ), - ), - 'PRIMARY KEY' => array('id'), - 'UNIQUE KEYS' => array( - 'username_idx' => array('username') - ), - 'INDEXES' => array( - 'registered_idx' => array('registered') - ) - ); - - if ($db_type == 'mysql' || $db_type == 'mysqli' || $db_type == 'mysql_innodb' || $db_type == 'mysqli_innodb') - $schema['UNIQUE KEYS']['username_idx'] = array('username(25)'); - - $db->create_table('users', $schema) or error('Unable to create users table', __FILE__, __LINE__, $db->error()); - - - $now = time(); - - // Insert the four preset groups - $db->query('INSERT INTO '.$db->prefix.'groups ('.($db_type != 'pgsql' ? 'g_id, ' : '').'g_title, g_user_title, g_moderator, g_mod_edit_users, g_mod_rename_users, g_mod_change_passwords, g_mod_ban_users, g_read_board, g_view_users, g_post_replies, g_post_topics, g_edit_posts, g_delete_posts, g_delete_topics, g_set_title, g_search, g_search_users, g_send_email, g_post_flood, g_search_flood, g_email_flood) VALUES('.($db_type != 'pgsql' ? '1, ' : '')."'Administrators', 'Administrator', 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0)") or error('Unable to add group', __FILE__, __LINE__, $db->error()); - - $db->query('INSERT INTO '.$db->prefix.'groups ('.($db_type != 'pgsql' ? 'g_id, ' : '').'g_title, g_user_title, g_moderator, g_mod_edit_users, g_mod_rename_users, g_mod_change_passwords, g_mod_ban_users, g_read_board, g_view_users, g_post_replies, g_post_topics, g_edit_posts, g_delete_posts, g_delete_topics, g_set_title, g_search, g_search_users, g_send_email, g_post_flood, g_search_flood, g_email_flood) VALUES('.($db_type != 'pgsql' ? '2, ' : '')."'Moderators', 'Moderator', 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0)") or error('Unable to add group', __FILE__, __LINE__, $db->error()); - - $db->query('INSERT INTO '.$db->prefix.'groups ('.($db_type != 'pgsql' ? 'g_id, ' : '').'g_title, g_user_title, g_moderator, g_mod_edit_users, g_mod_rename_users, g_mod_change_passwords, g_mod_ban_users, g_read_board, g_view_users, g_post_replies, g_post_topics, g_edit_posts, g_delete_posts, g_delete_topics, g_set_title, g_search, g_search_users, g_send_email, g_post_flood, g_search_flood, g_email_flood) VALUES('.($db_type != 'pgsql' ? '3, ' : '')."'Guest', NULL, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 60, 30, 0)") or error('Unable to add group', __FILE__, __LINE__, $db->error()); - - $db->query('INSERT INTO '.$db->prefix.'groups ('.($db_type != 'pgsql' ? 'g_id, ' : '').'g_title, g_user_title, g_moderator, g_mod_edit_users, g_mod_rename_users, g_mod_change_passwords, g_mod_ban_users, g_read_board, g_view_users, g_post_replies, g_post_topics, g_edit_posts, g_delete_posts, g_delete_topics, g_set_title, g_search, g_search_users, g_send_email, g_post_flood, g_search_flood, g_email_flood) VALUES('.($db_type != 'pgsql' ? '4, ' : '')."'Members', NULL, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 60, 30, 60)") or error('Unable to add group', __FILE__, __LINE__, $db->error()); - - // Insert guest and first admin user - $db->query('INSERT INTO '.$db_prefix."users (group_id, username, password, email) VALUES(3, 'Guest', 'Guest', 'Guest')") - or error('Unable to add guest user. Please check your configuration and try again', __FILE__, __LINE__, $db->error()); - - $db->query('INSERT INTO '.$db_prefix."users (group_id, username, password, email, num_posts, last_post, registered, registration_ip, last_visit) VALUES(1, '".$db->escape($username)."', '".pun_hash($password1)."', '$email', 1, ".$now.", ".$now.", '127.0.0.1', ".$now.')') - or error('Unable to add administrator user. Please check your configuration and try again', __FILE__, __LINE__, $db->error()); - - // Enable/disable avatars depending on file_uploads setting in PHP configuration - $avatars = in_array(strtolower(@ini_get('file_uploads')), array('on', 'true', '1')) ? 1 : 0; - - // Insert config data - $config = array( - 'o_cur_version' => "'".FORUM_VERSION."'", - 'o_database_revision' => "'".FORUM_DB_REVISION."'", - 'o_board_title' => "'".$db->escape($title)."'", - 'o_board_desc' => "'".$db->escape($description)."'", - 'o_default_timezone' => "'0'", - 'o_time_format' => "'H:i:s'", - 'o_date_format' => "'Y-m-d'", - 'o_timeout_visit' => "'1800'", - 'o_timeout_online' => "'300'", - 'o_redirect_delay' => "'1'", - 'o_show_version' => "'0'", - 'o_show_user_info' => "'1'", - 'o_show_post_count' => "'1'", - 'o_signatures' => "'1'", - 'o_smilies' => "'1'", - 'o_smilies_sig' => "'1'", - 'o_make_links' => "'1'", - 'o_default_lang' => "'".$db->escape($default_lang)."'", - 'o_default_style' => "'".$db->escape($default_style)."'", - 'o_default_user_group' => "'4'", - 'o_topic_review' => "'15'", - 'o_disp_topics_default' => "'30'", - 'o_disp_posts_default' => "'25'", - 'o_indent_num_spaces' => "'4'", - 'o_quote_depth' => "'3'", - 'o_quickpost' => "'1'", - 'o_users_online' => "'1'", - 'o_censoring' => "'0'", - 'o_ranks' => "'1'", - 'o_show_dot' => "'0'", - 'o_topic_views' => "'1'", - 'o_quickjump' => "'1'", - 'o_gzip' => "'0'", - 'o_additional_navlinks' => "''", - 'o_report_method' => "'0'", - 'o_regs_report' => "'0'", - 'o_default_email_setting' => "'1'", - 'o_mailing_list' => "'".$email."'", - 'o_avatars' => "'".$avatars."'", - 'o_avatars_dir' => "'img/avatars'", - 'o_avatars_width' => "'60'", - 'o_avatars_height' => "'60'", - 'o_avatars_size' => "'10240'", - 'o_search_all_forums' => "'1'", - 'o_base_url' => "'".$db->escape($base_url)."'", - 'o_admin_email' => "'".$email."'", - 'o_webmaster_email' => "'".$email."'", - 'o_subscriptions' => "'1'", - 'o_smtp_host' => "NULL", - 'o_smtp_user' => "NULL", - 'o_smtp_pass' => "NULL", - 'o_smtp_ssl' => "'0'", - 'o_regs_allow' => "'1'", - 'o_regs_verify' => "'0'", - 'o_announcement' => "'0'", - 'o_announcement_message' => "'Enter your announcement here.'", - 'o_rules' => "'0'", - 'o_rules_message' => "'Enter your rules here.'", - 'o_maintenance' => "'0'", - 'o_maintenance_message' => "'The forums are temporarily down for maintenance. Please try again in a few minutes.
    \\n
    \\n/Administrator'", - 'o_default_dst' => "'0'", - 'o_feed_type' => "'2'", - 'p_message_bbcode' => "'1'", - 'p_message_img_tag' => "'1'", - 'p_message_all_caps' => "'1'", - 'p_subject_all_caps' => "'1'", - 'p_sig_all_caps' => "'1'", - 'p_sig_bbcode' => "'1'", - 'p_sig_img_tag' => "'0'", - 'p_sig_length' => "'400'", - 'p_sig_lines' => "'4'", - 'p_allow_banned_email' => "'1'", - 'p_allow_dupe_email' => "'0'", - 'p_force_guest_email' => "'1'" - ); - - foreach ($config as $conf_name => $conf_value) - { - $db->query('INSERT INTO '.$db_prefix."config (conf_name, conf_value) VALUES('$conf_name', $conf_value)") - or error('Unable to insert into table '.$db_prefix.'config. Please check your configuration and try again', __FILE__, __LINE__, $db->error()); - } - - // Insert some other default data - $subject = 'Test post'; - $message = 'If you are looking at this (which I guess you are), the install of FluxBB appears to have worked! Now log in and head over to the administration control panel to configure your forum.'; - - $db->query('INSERT INTO '.$db_prefix."ranks (rank, min_posts) VALUES('New member', 0)") - or error('Unable to insert into table '.$db_prefix.'ranks. Please check your configuration and try again', __FILE__, __LINE__, $db->error()); - - $db->query('INSERT INTO '.$db_prefix."ranks (rank, min_posts) VALUES('Member', 10)") - or error('Unable to insert into table '.$db_prefix.'ranks. Please check your configuration and try again', __FILE__, __LINE__, $db->error()); - - $db->query('INSERT INTO '.$db_prefix."categories (cat_name, disp_position) VALUES('Test category', 1)") - or error('Unable to insert into table '.$db_prefix.'categories. Please check your configuration and try again', __FILE__, __LINE__, $db->error()); - - $db->query('INSERT INTO '.$db_prefix."forums (forum_name, forum_desc, num_topics, num_posts, last_post, last_post_id, last_poster, disp_position, cat_id) VALUES('Test forum', 'This is just a test forum', 1, 1, ".$now.", 1, '".$db->escape($username)."', 1, 1)") - or error('Unable to insert into table '.$db_prefix.'forums. Please check your configuration and try again', __FILE__, __LINE__, $db->error()); - - $db->query('INSERT INTO '.$db_prefix."topics (poster, subject, posted, first_post_id, last_post, last_post_id, last_poster, forum_id) VALUES('".$db->escape($username)."', '".$db->escape($subject)."', ".$now.", 1, ".$now.", 1, '".$db->escape($username)."', 1)") - or error('Unable to insert into table '.$db_prefix.'topics. Please check your configuration and try again', __FILE__, __LINE__, $db->error()); - - $db->query('INSERT INTO '.$db_prefix."posts (poster, poster_id, poster_ip, message, posted, topic_id) VALUES('".$db->escape($username)."', 2, '127.0.0.1', '".$db->escape($message)."', ".$now.', 1)') - or error('Unable to insert into table '.$db_prefix.'posts. Please check your configuration and try again', __FILE__, __LINE__, $db->error()); - - // Index the test post so searching for it works - require PUN_ROOT.'include/search_idx.php'; - $pun_config['o_default_lang'] = $default_lang; - update_search_index('post', 1, $message, $subject); - - $db->end_transaction(); - - - $alerts = array(); - // Check if the cache directory is writable - if (!@is_writable('./cache/')) - $alerts[] = 'The cache directory is currently not writable! In order for FluxBB to function properly, the directory named cache must be writable by PHP. Use chmod to set the appropriate directory permissions. If in doubt, chmod to 0777.'; - - // Check if default avatar directory is writable - if (!@is_writable('./img/avatars/')) - $alerts[] = 'The avatar directory is currently not writable! If you want users to be able to upload their own avatar images you must see to it that the directory named img/avatars is writable by PHP. You can later choose to save avatar images in a different directory (see Admin/Options). Use chmod to set the appropriate directory permissions. If in doubt, chmod to 0777.'; - - // Check if we disabled uploading avatars because file_uploads was disabled - if ($avatars == '0') - $alerts[] = 'File uploads appear to be disallowed on this server! If you want users to be able to upload their own avatar images you must enable the file_uploads configuration setting in PHP. Once file uploads have been enabled, avatar uploads can be enabled in Administration/Options/Features.'; - - // Add some random bytes at the end of the cookie name to prevent collisions - $cookie_name = 'pun_cookie_'.random_key(6, false, true); - - // Generate the config.php file data - $config = generate_config_file(); - - // Attempt to write config.php and serve it up for download if writing fails - $written = false; - if (is_writable(PUN_ROOT)) - { - $fh = @fopen(PUN_ROOT.'config.php', 'wb'); - if ($fh) - { - fwrite($fh, $config); - fclose($fh); - - $written = true; - } - } - - -?> - - - - - -FluxBB Installation - - - - - -
    -
    - -
    - -
    -
    -
    -

    FluxBB Installation

    -

    FluxBB has been installed. To finalize the installation please follow the instructions below.

    -
    -
    -
    - -
    - -
    -

    Final instructions

    -
    - -
    -
    -
    -

    To finalize the installation, you need to click on the button below to download a file called config.php. You then need to upload this file to the root directory of your FluxBB installation.

    -

    Once you have uploaded config.php, FluxBB will be fully installed! At that point, you may go to the forum index.

    -
    - - - - - - - - - - -
    -
      -'.$cur_alert.''."\n"; -?> -
    -
    -

    -
    - - -
    -
    -
    -

    FluxBB has been fully installed! You may now go to the forum index.

    -
    -
    -
    - -
    -
    - -
    - -
    - -
    -
    - - - - 'No user by that username registered. If you want to add a ban not tied to a specific username just leave the username blank.', -'No user ID message' => 'No user by that ID registered.', -'User is admin message' => 'The user %s is an administrator and can\'t be banned. If you want to ban an administrator, you must first demote him/her to moderator or user.', -'Must enter message' => 'You must enter either a username, an IP address or an email address (at least).', -'Cannot ban guest message' => 'The guest user cannot be banned.', -'Invalid IP message' => 'You entered an invalid IP/IP-range.', -'Invalid e-mail message' => 'The email address (e.g. user@domain.com) or partial email address domain (e.g. domain.com) you entered is invalid.', -'Invalid date message' => 'You entered an invalid expire date.', -'Invalid date reasons' => 'The format should be YYYY-MM-DD and the date must be at least one day in the future.', -'Ban added redirect' => 'Ban added. Redirecting …' , -'Ban edited redirect' => 'Ban edited. Redirecting …', -'Ban removed redirect' => 'Ban removed. Redirecting …', - -'New ban head' => 'New ban', -'Add ban subhead' => 'Add ban', -'Username label' => 'Username', -'Username help' => 'The username to ban (case-insensitive).', -'Username advanced help' => 'The username to ban (case-insensitive). The next page will let you enter a custom IP and email. If you just want to ban a specific IP/IP-range or email just leave it blank.', - -'Ban search head' => 'Ban search', -'Ban search subhead' => 'Enter search criteria', -'Ban search info' => 'Search for bans in the database. You can enter one or more terms to search for. Wildcards in the form of asterisks (*) are accepted.', -'Date help' => '(yyyy-mm-dd)', -'Message label' => 'Message', -'Expire after label' => 'Expire after', -'Expire before label' => 'Expire before', -'Order by label' => 'Order by', -'Order by username' => 'Username', -'Order by ip' => 'IP', -'Order by e-mail' => 'Email', -'Order by expire' => 'Expire date', -'Ascending' => 'Ascending', -'Descending' => 'Descending', -'Submit search' => 'Submit search', - -'E-mail label' => 'Email', -'E-mail help' => 'The email or email domain you wish to ban (e.g. someone@somewhere.com or somewhere.com). See "Allow banned email addresses" in Permissions for more info.', -'IP label' => 'IP address/IP-ranges', -'IP help' => 'The IP address or IP-ranges you wish to ban (e.g. 150.11.110.1 or 150.11.110). Separate addresses with spaces. If an IP is entered already it is the last known IP of this user in the database.', -'IP help link' => 'Click %s to see IP statistics for this user.', -'Reason label' => 'Reason', -'Banned by label' => 'Banned by', -'Ban advanced head' => 'Ban advanced settings', -'Ban advanced subhead' => 'Supplement ban with IP and email', -'Ban message label' => 'Ban message', -'Ban message help' => 'A message that will be displayed to the banned user when he/she visits the board.', -'Message expiry subhead' => 'Ban message and expiry', -'Ban IP range info' => 'You should be very careful when banning an IP-range because of the possibility of multiple users matching the same partial IP.', -'Expire date label' => 'Expire date', -'Expire date help' => 'The date when this ban should be automatically removed (format: yyyy-mm-dd). Leave blank to remove manually.', - -'Results head' => 'Search Results', -'Results username head' => 'Username', -'Results e-mail head' => 'Email', -'Results IP address head' => 'IP/IP-ranges', -'Results expire head' => 'Expires', -'Results message head' => 'Message', -'Results banned by head' => 'Banned by', -'Results actions head' => 'Actions', -'No match' => 'No match', -'Unknown' => 'Unknown', - -); diff --git a/upload/lang/English/admin_categories.php b/upload/lang/English/admin_categories.php deleted file mode 100644 index 311a5af..0000000 --- a/upload/lang/English/admin_categories.php +++ /dev/null @@ -1,29 +0,0 @@ - 'You must enter a name for the category', -'Category added redirect' => 'Category added. Redirecting …', -'Category deleted redirect' => 'Category deleted. Redirecting …', -'Delete category head' => 'Delete category (together with all forums and posts it contains)', -'Confirm delete subhead' => 'Confirm delete category', -'Confirm delete info' => 'Are you sure that you want to delete the category %s?', -'Delete category warn' => 'WARNING! Deleting a category will delete all forums and posts (if any) in this category!', -'Must enter integer message' => 'Position must be a positive integer value.', -'Categories updated redirect' => 'Categories updated. Redirecting …', -'Add categories head' => 'Add categories', -'Add categories subhead' => 'Add categories', -'Add category label' => 'Add a new category', -'Add new submit' => 'Add new', -'Add category help' => 'The name of the new category you want to add. You can edit the name of the category later (see below). Go to %s to add forums to your new category.', -'Delete categories head' => 'Delete categories', -'Delete categories subhead' => 'Delete categories', -'Delete category label' => 'Delete a category', -'Delete category help' => 'Select the name of the category you want to delete. You will be asked to confirm your choice of category for deletion before it is deleted.', -'Edit categories head' => 'Edit categories', -'Edit categories subhead' => 'Edit categories', -'Category position label' => 'Position', -'Category name label' => 'Name', - -); diff --git a/upload/lang/English/admin_censoring.php b/upload/lang/English/admin_censoring.php deleted file mode 100644 index f112ba1..0000000 --- a/upload/lang/English/admin_censoring.php +++ /dev/null @@ -1,20 +0,0 @@ - 'You must enter both a word to censor and text to replace it with.', -'Must search both message' => 'You must enter both text to search for and text to replace with.', -'Word updated redirect' => 'Censor word updated. Redirecting …', -'Word added redirect' => 'Censor word added. Redirecting …', -'Word removed redirect' => 'Censor word removed. Redirecting …', -'Censoring head' => 'Censoring', -'Add word subhead' => 'Add word', -'Add word info' => 'Enter a word that you want to censor and the replacement text for this word. Wildcards are accepted (i.e. *some* would match somewhere and lonesome). Censor words also affect usernames. New users will not be able to register with usernames containing any censored words. The search is case insensitive. Censor words must be enabled in %s for this to have any effect.', -'Censored word label' => 'Censored word', -'Replacement label' => 'Replacement word(s)', -'Action label' => 'Action', -'Edit remove subhead' => 'Edit or remove words', -'No words in list' => 'No censor words in list.', - -); diff --git a/upload/lang/English/admin_common.php b/upload/lang/English/admin_common.php deleted file mode 100644 index a87616c..0000000 --- a/upload/lang/English/admin_common.php +++ /dev/null @@ -1,44 +0,0 @@ - 'Admin menu', -'Plugins menu' => 'Plugins menu', -'Moderator menu' => 'Moderator menu', -'Index' => 'Index', -'Categories' => 'Categories', -'Forums' => 'Forums', -'Users' => 'Users', -'User groups' => 'User groups', -'Options' => 'Options', -'Permissions' => 'Permissions', -'Censoring' => 'Censoring', -'Ranks' => 'Ranks', -'Bans' => 'Bans', -'Prune' => 'Prune', -'Maintenance' => 'Maintenance', -'Reports' => 'Reports', - -'Admin' => 'Admin', -'Go back' => 'Go back', -'Delete' => 'Delete', -'Update' => 'Update', -'Add' => 'Add', -'Edit' => 'Edit', -'Remove' => 'Remove', -'Yes' => 'Yes', -'No' => 'No', -'Save changes' => 'Save changes', -'Save' => 'Save', -'here' => 'here', -'Action' => 'Action', -'None' => 'None', -'Maintenance mode' => 'maintenance mode', // Used for link text in more than one file - -// Admin loader -'No plugin message' => 'There is no plugin called %s in the plugin directory.', -'Plugin failed message' => 'Loading of the plugin - %s - failed.', - -); diff --git a/upload/lang/English/admin_forums.php b/upload/lang/English/admin_forums.php deleted file mode 100644 index f13876d..0000000 --- a/upload/lang/English/admin_forums.php +++ /dev/null @@ -1,51 +0,0 @@ - 'Forum added. Redirecting …', -'Forum deleted redirect' => 'Forum deleted. Redirecting …', -'Forums updated redirect' => 'Forums updated. Redirecting …', -'Forum updated redirect' => 'Forum updated. Redirecting …', -'Perms reverted redirect' => 'Permissions reverted to defaults. Redirecting …', -'Must enter name message' => 'You must enter a forum name.', -'Must be integer message' => 'Position must be a positive integer value.', - -// Entry page -'Add forum head' => 'Add forum', -'Create new subhead' => 'Create a new forum', -'Add forum label' => 'Add forum to category', -'Add forum help' => 'Select the category to which you wish to add a new forum.', -'Add forum' => 'Add forum', -'No categories exist' => 'No categories exist', -'Edit forums head' => 'Edit forums', -'Category subhead' => 'Category:', -'Forum label' => 'Forum', -'Edit link' => 'Edit', -'Delete link' => 'Delete', -'Position label' => 'Position', -'Update positions' => 'Update positions', -'Confirm delete head' => 'Confirm delete forum', -'Confirm delete subhead' => 'Important! Read before deleting', -'Confirm delete info' => 'Are you sure that you want to delete the forum %s?', -'Confirm delete warn' => 'WARNING! Deleting a forum will delete all posts (if any) in that forum!', - -// Detailed edit page -'Edit forum head' => 'Edit forum', -'Edit details subhead' => 'Edit forum details', -'Forum name label' => 'Forum name', -'Forum description label' => 'Description (HTML)', -'Category label' => 'Category', -'Sort by label' => 'Sort topics by', -'Last post' => 'Last post', -'Topic start' => 'Topic start', -'Redirect label' => 'Redirect URL', -'Redirect help' => 'Only available in empty forums', -'Group permissions subhead' => 'Edit group permissions for this forum', -'Group permissions info' => 'In this form, you can set the forum specific permissions for the different user groups. If you haven\'t made any changes to this forum\'s group permissions, what you see below is the default based on settings in %s. Administrators always have full permissions and are thus excluded. Permission settings that differ from the default permissions for the user group are marked red. The "Read forum" permission checkbox will be disabled if the group in question lacks the "Read board" permission. For redirect forums, only the "Read forum" permission is editable.', -'Read forum label' => 'Read forum', -'Post replies label' => 'Post replies', -'Post topics label' => 'Post topics', -'Revert to default' => 'Revert to default', - -); diff --git a/upload/lang/English/admin_groups.php b/upload/lang/English/admin_groups.php deleted file mode 100644 index dd6ad56..0000000 --- a/upload/lang/English/admin_groups.php +++ /dev/null @@ -1,82 +0,0 @@ - 'You must enter a group title.', -'Title already exists message' => 'There is already a group with the title %s.', -'Default group redirect' => 'Default group set. Redirecting …', -'Cannot remove default message' => 'The default group cannot be removed. In order to delete this group, you must first setup a different group as the default.', -'Group removed redirect' => 'Group removed. Redirecting …', -'Group added redirect' => 'Group added. Redirecting …', -'Group edited redirect' => 'Group edited. Redirecting …', - -'Add groups head' => 'Add/setup groups', -'Add group subhead' => 'Add new group', -'New group label' => 'Base new group on', -'New group help' => 'Select a user group from which the new group will inherit its permission settings. The next page will let you fine-tune its settings.', -'Default group subhead' => 'Set default group', -'Default group label' => 'Default group', -'Default group help' => 'This is the default user group, e.g. the group users are placed in when they register. For security reasons, users can\'t be placed in either the moderator or administrator user groups by default.', -'Existing groups head' => 'Existing groups', -'Edit groups subhead' => 'Edit/delete groups', -'Edit groups info' => 'The pre-defined groups Guests, Administrators, Moderators and Members cannot be removed. However, they can be edited. Please note that in some groups, some options are unavailable (e.g. the edit posts permission for guests). Administrators always have full permissions.', -'Edit link' => 'Edit', -'Delete link' => 'Delete', -'Group delete head' => 'Group delete', -'Confirm delete subhead' => 'Confirm delete group', -'Confirm delete info' => 'Are you sure that you want to delete the group %s?', -'Confirm delete warn' => 'WARNING! After you deleted a group you can not restore it.', -'Delete group head' => 'Delete group', -'Move users subhead' => 'Move users currently in group', -'Move users info' => 'The group %s currently has %s members. Please select a group to which these members will be assigned upon deletion.', -'Move users label' => 'Move users to', -'Delete group' => 'Delete group', - -'Group settings head' => 'Group settings', -'Group settings subhead' => 'Setup group options and permissions', -'Group settings info' => 'Below options and permissions are the default permissions for the user group. These options apply if no forum specific permissions are in effect.', -'Group title label' => 'Group title', -'User title label' => 'User title', -'User title help' => 'This title will override any rank users in this group have attained. Leave blank to use default title or rank.', -'Mod privileges label' => 'Allow users moderator privileges', -'Mod privileges help' => 'In order for a user in this group to have moderator abilities, he/she must be assigned to moderate one or more forums. This is done via the user administration page of the user\'s profile.', -'Edit profile label' => 'Allow moderators to edit user profiles', -'Edit profile help' => 'If moderator privileges are enabled, allow users in this group to edit user profiles.', -'Rename users label' => 'Allow moderators to rename users', -'Rename users help' => 'If moderator privileges are enabled, allow users in this group to rename users.', -'Change passwords label' => 'Allow moderators to change passwords', -'Change passwords help' => 'If moderator privileges are enabled, allow users in this group to change user passwords.', -'Ban users label' => 'Allow moderators to ban users', -'Ban users help' => 'If moderator privileges are enabled, allow users in this group to ban users.', -'Read board label' => 'Read board', -'Read board help' => 'Allow users in this group to view the board. This setting applies to every aspect of the board and can therefore not be overridden by forum specific settings. If this is set to "No", users in this group will only be able to login/logout and register.', -'View user info label' => 'View user information', -'View user info help' => 'Allow users to view the user list and user profiles.', -'Post replies label' => 'Post replies', -'Post replies help' => 'Allow users in this group to post replies in topics.', -'Post topics label' => 'Post topics', -'Post topics help' => 'Allow users in this group to post new topics.', -'Edit posts label' => 'Edit posts', -'Edit posts help' => 'Allow users in this group to edit their own posts.', -'Delete posts label' => 'Delete posts', -'Delete posts help' => 'Allow users in this group to delete their own posts.', -'Delete topics label' => 'Delete topics', -'Delete topics help' => 'Allow users in this group to delete their own topics (including any replies).', -'Set own title label' => 'Set own user title', -'Set own title help' => 'Allow users in this group to set their own user title.', -'User search label' => 'Use search', -'User search help' => 'Allow users in this group to use the search feature.', -'User list search label' => 'Search user list', -'User list search help' => 'Allow users in this group to freetext search for users in the user list.', -'Send e-mails label' => 'Send e-mails', -'Send e-mails help' => 'Allow users in this group to send e-mails to other users.', -'Post flood label' => 'Post flood interval', -'Post flood help' => 'Number of seconds that users in this group have to wait between posts. Set to 0 to disable.', -'Search flood label' => 'Search flood interval', -'Search flood help' => 'Number of seconds that users in this group have to wait between searches. Set to 0 to disable.', -'E-mail flood label' => 'Email flood interval', -'E-mail flood help' => 'Number of seconds that users in this group have to wait between emails. Set to 0 to disable.', -'Moderator info' => 'Please note that in order for a user in this group to have moderator abilities, he/she must be assigned to moderate one or more forums. This is done via the user administration page of the user\'s profile.', - -); diff --git a/upload/lang/English/admin_index.php b/upload/lang/English/admin_index.php deleted file mode 100644 index 9f9cdc7..0000000 --- a/upload/lang/English/admin_index.php +++ /dev/null @@ -1,51 +0,0 @@ - 'Unable to check for upgrade since \'allow_url_fopen\' is disabled on this system.', -'Upgrade check failed message' => 'Check for upgrade failed for unknown reasons.', -'Running latest version message' => 'You are running the latest version of FluxBB.', -'New version available message' => 'A new version of FluxBB has been released. You can download the latest version at %s.', -'PHPinfo disabled message' => 'The PHP function phpinfo() has been disabled on this server.', -'Not available' => 'Not available', -'Forum admin head' => 'Forum administration', -'NA' => 'N/A', -'Welcome to admin' => 'Welcome to the FluxBB administration control panel. From here you can control vital aspects of the board. Depending on whether you are an administrator or a moderator you can:', -'Welcome 1' => 'Organize categories and forums.', -'Welcome 2' => 'Set forum-wide options and preferences.', -'Welcome 3' => 'Control permissions for users and guests.', -'Welcome 4' => 'View IP statistics for users.', -'Welcome 5' => 'Ban users.', -'Welcome 6' => 'Censor words.', -'Welcome 7' => 'Set up user ranks.', -'Welcome 8' => 'Prune old posts.', -'Welcome 9' => 'Handle post reports.', -'Statistics head' => 'Statistics', -'FluxBB version label' => 'FluxBB version', -'Check for upgrade' => 'Check for upgrade', -'FluxBB version data' => 'v%s - %s', -'Server load label' => 'Server load', -'Server load data' => '%s - %s user(s) online', -'Environment label' => 'Environment', -'Environment data OS' => 'Operating system: %s', -'Show info' => 'Show info', -'Environment data version' => 'PHP: %s - %s', -'Environment data acc' => 'Accelerator: %s', -'Turck MMCache' => 'Turk MMCache', -'Turck MMCache link' => 'turck-mmcache.sourceforge.net', -'ionCube PHP Accelerator' => 'ionCube PHP Accelerator', -'ionCube PHP Accelerator link' => 'www.php-accelerator.co.uk/', -'Alternative PHP Cache (APC)' => 'Alternative PHP Cache (APC)', -'Alternative PHP Cache (APC) link' => 'www.php.net/apc/', -'Zend Optimizer' => 'Zend Optimizer', -'Zend Optimizer link' => 'www.zend.com/products/guard/zend-optimizer', -'eAccelerator' => 'eAccelerator', -'eAccelerator link' => 'www.eaccelerator.net/', -'XCache' => 'XCache', -'XCache link' => 'xcache.lighttpd.net/', -'Database label' => 'Database', -'Database data rows' => 'Rows: %s', -'Database data size' => 'Size: %s', - -); diff --git a/upload/lang/English/admin_maintenance.php b/upload/lang/English/admin_maintenance.php deleted file mode 100644 index a0e62b3..0000000 --- a/upload/lang/English/admin_maintenance.php +++ /dev/null @@ -1,23 +0,0 @@ - 'Forum maintenance', -'Rebuild index subhead' => 'Rebuild search index', -'Rebuild index info' => 'If you\'ve added, edited or removed posts manually in the database or if you\'re having problems searching, you should rebuild the search index. For best performance, you should put the forum in %s during rebuilding. Rebuilding the search index can take a long time and will increase server load during the rebuild process!', -'Posts per cycle label' => 'Posts per cycle', -'Posts per cycle help' => 'The number of posts to process per pageview. E.g. if you were to enter 300, three hundred posts would be processed and then the page would refresh. This is to prevent the script from timing out during the rebuild process.', -'Starting post label' => 'Starting post ID', -'Starting post help' => 'The post ID to start rebuilding at. The default value is the first available ID in the database. Normally you wouldn\'t want to change this.', -'Empty index label' => 'Empty index', -'Empty index help' => 'Select this if you want the search index to be emptied before rebuilding (see below).', -'Rebuild completed info' => 'Once the process has completed, you will be redirected back to this page. It is highly recommended that you have JavaScript enabled in your browser during rebuilding (for automatic redirect when a cycle has completed). If you are forced to abort the rebuild process, make a note of the last processed post ID and enter that ID+1 in "Starting post ID" when/if you want to continue ("Empty index" must not be selected).', -'Rebuild index' => 'Rebuild index', -'Rebuilding search index' => 'Rebuilding search index', -'Rebuilding index info' => 'Rebuilding index. This might be a good time to put on some coffee :-)', -'Processing post' => 'Processing post %s …', -'Click here' => 'Click here', -'Javascript redirect failed' => 'JavaScript redirect unsuccessful. %s to continue …', - -); diff --git a/upload/lang/English/admin_options.php b/upload/lang/English/admin_options.php deleted file mode 100644 index e701917..0000000 --- a/upload/lang/English/admin_options.php +++ /dev/null @@ -1,217 +0,0 @@ - 'Bad HTTP_REFERER. If you have moved these forums from one location to another or switched domains, you need to update the Base URL manually in the database (look for o_base_url in the config table) and then clear the cache by deleting all .php files in the /cache directory.', -'Must enter title message' => 'You must enter a board title.', -'Invalid e-mail message' => 'The admin email address you entered is invalid.', -'Invalid webmaster e-mail message' => 'The webmaster email address you entered is invalid.', -'Enter announcement here' => 'Enter your announcement here.', -'Enter rules here' => 'Enter your rules here.', -'Default maintenance message' => 'The forums are temporarily down for maintenance. Please try again in a few minutes.', -'Timeout error message' => 'The value of "Timeout online" must be smaller than the value of "Timeout visit".', -'Options updated redirect' => 'Options updated. Redirecting …', -'Options head' => 'Options', - -// Essentials section -'Essentials subhead' => 'Essentials', -'Board title label' => 'Board title', -'Board title help' => 'The title of this bulletin board (shown at the top of every page). This field may not contain HTML.', -'Board desc label' => 'Board description', -'Board desc help' => 'A short description of this bulletin board (shown at the top of every page). This field may contain HTML.', -'Base URL label' => 'Base URL', -'Base URL help' => 'The complete URL of the board without trailing slash (i.e. http://www.mydomain.com/forums). This must be correct in order for all admin and moderator features to work. If you get "Bad referer" errors, it\'s probably incorrect.', -'Timezone label' => 'Default time zone', -'Timezone help' => 'The default time zone for guests and users attempting to register for the board.', -'DST label' => 'Adjust for DST', -'DST help' => 'Check if daylight savings is in effect (advances times by 1 hour).', -'Language label' => 'Default language', -'Language help' => 'The default language for guests and users who haven\'t changed from the default in their profile. If you remove a language pack, this must be updated.', -'Default style label' => 'Default style', -'Default style help' => 'The default style for guests and users who haven\'t changed from the default in their profile.', - -// Essentials section timezone options -'UTC-12:00' => '(UTC-12:00) International Date Line West', -'UTC-11:00' => '(UTC-11:00) Niue, Samoa', -'UTC-10:00' => '(UTC-10:00) Hawaii-Aleutian, Cook Island', -'UTC-09:30' => '(UTC-09:30) Marquesas Islands', -'UTC-09:00' => '(UTC-09:00) Alaska, Gambier Island', -'UTC-08:30' => '(UTC-08:30) Pitcairn Islands', -'UTC-08:00' => '(UTC-08:00) Pacific', -'UTC-07:00' => '(UTC-07:00) Mountain', -'UTC-06:00' => '(UTC-06:00) Central', -'UTC-05:00' => '(UTC-05:00) Eastern', -'UTC-04:00' => '(UTC-04:00) Atlantic', -'UTC-03:30' => '(UTC-03:30) Newfoundland', -'UTC-03:00' => '(UTC-03:00) Amazon, Central Greenland', -'UTC-02:00' => '(UTC-02:00) Mid-Atlantic', -'UTC-01:00' => '(UTC-01:00) Azores, Cape Verde, Eastern Greenland', -'UTC' => '(UTC) Western European, Greenwich', -'UTC+01:00' => '(UTC+01:00) Central European, West African', -'UTC+02:00' => '(UTC+02:00) Eastern European, Central African', -'UTC+03:00' => '(UTC+03:00) Moscow, Eastern African', -'UTC+03:30' => '(UTC+03:30) Iran', -'UTC+04:00' => '(UTC+04:00) Gulf, Samara', -'UTC+04:30' => '(UTC+04:30) Afghanistan', -'UTC+05:00' => '(UTC+05:00) Pakistan, Yekaterinburg', -'UTC+05:30' => '(UTC+05:30) India, Sri Lanka', -'UTC+05:45' => '(UTC+05:45) Nepal', -'UTC+06:00' => '(UTC+06:00) Bangladesh, Bhutan, Novosibirsk', -'UTC+06:30' => '(UTC+06:30) Cocos Islands, Myanmar', -'UTC+07:00' => '(UTC+07:00) Indochina, Krasnoyarsk', -'UTC+08:00' => '(UTC+08:00) Greater China, Australian Western, Irkutsk', -'UTC+08:45' => '(UTC+08:45) Southeastern Western Australia', -'UTC+09:00' => '(UTC+09:00) Japan, Korea, Chita', -'UTC+09:30' => '(UTC+09:30) Australian Central', -'UTC+10:00' => '(UTC+10:00) Australian Eastern, Vladivostok', -'UTC+10:30' => '(UTC+10:30) Lord Howe', -'UTC+11:00' => '(UTC+11:00) Solomon Island, Magadan', -'UTC+11:30' => '(UTC+11:30) Norfolk Island', -'UTC+12:00' => '(UTC+12:00) New Zealand, Fiji, Kamchatka', -'UTC+12:45' => '(UTC+12:45) Chatham Islands', -'UTC+13:00' => '(UTC+13:00) Tonga, Phoenix Islands', -'UTC+14:00' => '(UTC+14:00) Line Islands', - -// Timeout Section -'Timeouts subhead' => 'Time and timeouts', -'Time format label' => 'Time format', -'PHP manual' => 'PHP manual', -'Time format help' => '[Current format: %s]. See %s for formatting options.', -'Date format label' => 'Date format', -'Date format help' => '[Current format: %s]. See %s for formatting options.', -'Visit timeout label' => 'Visit timeout', -'Visit timeout help' => 'Number of seconds a user must be idle before his/hers last visit data is updated (primarily affects new message indicators).', -'Online timeout label' => 'Online timeout', -'Online timeout help' => 'Number of seconds a user must be idle before being removed from the online users list.', -'Redirect time label' => 'Redirect time', -'Redirect time help' => 'Number of seconds to wait when redirecting. If set to 0, no redirect page will be displayed (not recommended).', - -// Display Section -'Display subhead' => 'Display', -'Version number label' => 'Version number', -'Version number help' => 'Show FluxBB version number in footer.', -'Info in posts label' => 'User info in posts', -'Info in posts help' => 'Show information about the poster under the username in topic view. The information affected is location, register date, post count and the contact links (email and URL).', -'Post count label' => 'User post count', -'Post count help' => 'Show the number of posts a user has made (affects topic view, profile and user list).', -'Smilies label' => 'Smilies in posts', -'Smilies help' => 'Convert smilies to small graphic icons.', -'Smilies sigs label' => 'Smilies in signatures', -'Smilies sigs help' => 'Convert smilies to small graphic icons in user signatures.', -'Clickable links label' => 'Make clickable links', -'Clickable links help' => 'When enabled, FluxBB will automatically detect any URLs in posts and make them clickable hyperlinks.', -'Topic review label' => 'Topic review', -'Topic review help' => 'Maximum number of posts to display when posting (newest first). Set to 0 to disable.', -'Topics per page label' => 'Topics per page', -'Topics per page help' => 'The default number of topics to display per page in a forum. Users can personalize this setting.', -'Posts per page label' => 'Posts per page', -'Posts per page help' => 'The default number of posts to display per page in a topic. Users can personalize this setting.', -'Indent label' => 'Indent size', -'Indent help' => 'If set to 8, a regular tab will be used when displaying text within the [code][/code] tag. Otherwise this many spaces will be used to indent the text.', -'Quote depth label' => 'Maximum [quote] depth', -'Quote depth help' => 'The maximum times a [quote] tag can go inside other [quote] tags, any tags deeper than this will be discarded.', - -// Features section -'Features subhead' => 'Features', -'Quick post label' => 'Quick post', -'Quick post help' => 'When enabled, FluxBB will add a quick post form at the bottom of topics. This way users can post directly from the topic view.', -'Users online label' => 'Users online', -'Users online help' => 'Display info on the index page about guests and registered users currently browsing the board.', -'Censor words label' => 'Censor words', -'Censor words help' => 'Enable this to censor specific words in the board. See %s for more info.', -'Signatures label' => 'Signatures', -'Signatures help' => 'Allow users to attach a signature to their posts.', -'User ranks label' => 'User ranks', -'User ranks help' => 'Enable this to use user ranks. See %s for more info.', -'User has posted label' => 'User has posted earlier', -'User has posted help' => 'This feature displays a dot in front of topics in viewforum.php in case the currently logged in user has posted in that topic earlier. Disable if you are experiencing high server load.', -'Topic views label' => 'Topic views', -'Topic views help' => 'Keep track of the number of views a topic has. Disable if you are experiencing high server load in a busy forum.', -'Quick jump label' => 'Quick jump', -'Quick jump help' => 'Enable the quick jump (jump to forum) drop list.', -'GZip label' => 'GZip output', -'GZip help' => 'If enabled, FluxBB will gzip the output sent to browsers. This will reduce bandwidth usage, but use a little more CPU. This feature requires that PHP is configured with zlib (--with-zlib). Note: If you already have one of the Apache modules mod_gzip or mod_deflate set up to compress PHP scripts, you should disable this feature.', -'Search all label' => 'Search all forums', -'Search all help' => 'When disabled, searches will only be allowed in one forum at a time. Disable if server load is high due to excessive searching.', -'Menu items label' => 'Additional menu items', -'Menu items help' => 'By entering HTML hyperlinks into this textbox, any number of items can be added to the navigation menu at the top of all pages. The format for adding new links is X = <a href="URL">LINK</a> where X is the position at which the link should be inserted (e.g. 0 to insert at the beginning and 2 to insert after "User list"). Separate entries with a linebreak.', -'Default feed label' => 'Default feed type', -'Default feed help' => 'Select the type of syndication feed to display. Note: Choosing none will not disable feeds, only hide them by default.', -'None' => 'None', -'RSS' => 'RSS', -'Atom' => 'Atom', - -// Reports section -'Reports subhead' => 'Reports', -'Reporting method label' => 'Reporting method', -'Internal' => 'Internal', -'By e-mail' => 'Email', -'Both' => 'Both', -'Reporting method help' => 'Select the method for handling topic/post reports. You can choose whether topic/post reports should be handled by the internal report system, emailed to the addresses on the mailing list (see below) or both.', -'Mailing list label' => 'Mailing list', -'Mailing list help' => 'A comma separated list of subscribers. The people on this list are the recipients of reports.', - -// Avatars section -'Avatars subhead' => 'Avatars', -'Use avatars label' => 'Use avatars', -'Use avatars help' => 'When enabled, users will be able to upload an avatar which will be displayed under their title/rank.', -'Upload directory label' => 'Upload directory', -'Upload directory help' => 'The upload directory for avatars (relative to the FluxBB root directory). PHP must have write permissions to this directory.', -'Max width label' => 'Max width', -'Max width help' => 'The maximum allowed width of avatars in pixels (60 is recommended).', -'Max height label' => 'Max height', -'Max height help' => 'The maximum allowed height of avatars in pixels (60 is recommended).', -'Max size label' => 'Max size', -'Max size help' => 'The maximum allowed size of avatars in bytes (10240 is recommended).', - -// E-mail section -'E-mail subhead' => 'Email', -'Admin e-mail label' => 'Admin email', -'Admin e-mail help' => 'The email address of the board administrator.', -'Webmaster e-mail label' => 'Webmaster email', -'Webmaster e-mail help' => 'This is the address that all emails sent by the board will be addressed from.', -'Subscriptions label' => 'Subscriptions', -'Subscriptions help' => 'Enable users to subscribe to topics (receive email when someone replies).', -'SMTP address label' => 'SMTP server address', -'SMTP address help' => 'The address of an external SMTP server to send emails with. You can specify a custom port number if the SMTP server doesn\'t run on the default port 25 (example: mail.myhost.com:3580). Leave blank to use the local mail program.', -'SMTP username label' => 'SMTP username', -'SMTP username help' => 'Username for SMTP server. Only enter a username if it is required by the SMTP server (most servers do not require authentication).', -'SMTP password label' => 'SMTP password', -'SMTP password help' => 'Password for SMTP server. Only enter a password if it is required by the SMTP server (most servers do not require authentication).', -'SMTP SSL label' => 'Encrypt SMTP using SSL', -'SMTP SSL help' => 'Encrypts the connection to the SMTP server using SSL. Should only be used if your SMTP server requires it and your version of PHP supports SSL.', - -// Registration Section -'Registration subhead' => 'Registration', -'Allow new label' => 'Allow new registrations', -'Allow new help' => 'Controls whether this board accepts new registrations. Disable only under special circumstances.', -'Verify label' => 'Verify registrations', -'Verify help' => 'When enabled, users are emailed a random password when they register. They can then log in and change the password in their profile if they see fit. This feature also requires users to verify new email addresses if they choose to change from the one they registered with. This is an effective way of avoiding registration abuse and making sure that all users have "correct" email addresses in their profiles.', -'Report new label' => 'Report new registrations', -'Report new help' => 'If enabled, FluxBB will notify users on the mailing list (see above) when a new user registers in the forums.', -'Use rules label' => 'User forum rules', -'Use rules help' => 'When enabled, users must agree to a set of rules when registering (enter text below). The rules will always be available through a link in the navigation table at the top of every page.', -'Rules label' => 'Enter your rules here', -'Rules help' => 'Here you can enter any rules or other information that the user must review and accept when registering. If you enabled rules above you have to enter something here, otherwise it will be disabled. This text will not be parsed like regular posts and thus may contain HTML.', -'E-mail default label' => 'Default email setting', -'E-mail default help' => 'Choose the default privacy setting for new user registrations.', -'Display e-mail label' => 'Display email address to other users.', -'Hide allow form label' => 'Hide email address but allow form e-mail.', -'Hide both label' => 'Hide email address and disallow form email.', - -// Announcement Section -'Announcement subhead' => 'Announcements', -'Display announcement label' => 'Display announcement', -'Display announcement help' => 'Enable this to display the below message in the board.', -'Announcement message label' => 'Announcement message', -'Announcement message help' => 'This text will not be parsed like regular posts and thus may contain HTML.', - -// Maintenance Section -'Maintenance subhead' => 'Maintenance', -'Maintenance mode label' => 'Maintenance mode', -'Maintenance mode help' => 'When enabled, the board will only be available to administrators. This should be used if the board needs to be taken down temporarily for maintenance. WARNING! Do not log out when the board is in maintenance mode. You will not be able to login again.', -'Maintenance message label' => 'Maintenance message', -'Maintenance message help' => 'The message that will be displayed to users when the board is in maintenance mode. If left blank, a default message will be used. This text will not be parsed like regular posts and thus may contain HTML.', - -); diff --git a/upload/lang/English/admin_permissions.php b/upload/lang/English/admin_permissions.php deleted file mode 100644 index 3c3600c..0000000 --- a/upload/lang/English/admin_permissions.php +++ /dev/null @@ -1,36 +0,0 @@ - 'Permissions updated. Redirecting …', -'Permissions head' => 'Permissions', -'Posting subhead' => 'Posting', -'BBCode label' => 'BBCode', -'BBCode help' => 'Allow BBCode in posts (recommended).', -'Image tag label' => 'Image tag', -'Image tag help' => 'Allow the BBCode [img][/img] tag in posts.', -'All caps message label' => 'All caps message', -'All caps message help' => 'Allow a message to contain only capital letters.', -'All caps subject label' => 'All caps subject', -'All caps subject help' => 'Allow a subject to contain only capital letters.', -'Require e-mail label' => 'Require guest email', -'Require e-mail help' => 'Require guests to supply an email address when posting.', -'Signatures subhead' => 'Signatures', -'BBCode sigs label' => 'BBCodes in signatures', -'BBCode sigs help' => 'Allow BBCodes in user signatures.', -'Image tag sigs label' => 'Image tag in signatures', -'Image tag sigs help' => 'Allow the BBCode [img][/img] tag in user signatures (not recommended).', -'All caps sigs label' => 'All caps signature', -'All caps sigs help' => 'Allow a signature to contain only capital letters.', -'Max sig length label' => 'Maximum signature length', -'Max sig length help' => 'The maximum number of characters a user signature may contain.', -'Max sig lines label' => 'Maximum signature lines', -'Max sig lines help' => 'The maximum number of lines a user signature may contain.', -'Registration subhead' => 'Registration', -'Banned e-mail label' => 'Allow banned email addresses', -'Banned e-mail help' => 'Allow users to register with or change to a banned email address/domain. If left at its default setting (yes), this action will be allowed, but an alert email will be sent to the mailing list (an effective way of detecting multiple registrations).', -'Duplicate e-mail label' => 'Allow duplicate email addresses', -'Duplicate e-mail help' => 'Controls whether users should be allowed to register with an email address that another user already has. If allowed, an alert email will be sent to the mailing list if a duplicate is detected.', - -); diff --git a/upload/lang/English/admin_plugin_example.php b/upload/lang/English/admin_plugin_example.php deleted file mode 100644 index b06158d..0000000 --- a/upload/lang/English/admin_plugin_example.php +++ /dev/null @@ -1,17 +0,0 @@ - 'You didn\'t enter anything!', -'Example plugin title' => 'Example plugin', -'You said' => 'You said "%s". Great stuff.', -'Explanation 1' => 'This plugin doesn\'t do anything useful. Hence the name "Example".', -'Explanation 2' => 'This would be a good spot to talk a little about your plugin. Describe what it does and how it should be used. Be brief, but informative.', -'Example form title' => 'An example form', -'Legend text' => 'Enter a piece of text and hit "Show text"!', -'Text to show' => 'Text to show', -'Show text button' => 'Show text', -'Input content' => 'The text you want to display.', - -); diff --git a/upload/lang/English/admin_prune.php b/upload/lang/English/admin_prune.php deleted file mode 100644 index b7f9030..0000000 --- a/upload/lang/English/admin_prune.php +++ /dev/null @@ -1,23 +0,0 @@ - 'Days to prune must be a positive integer value.', -'No old topics message' => 'There are no topics that are %s days old. Please decrease the value of "Days old" and try again.', -'Posts pruned redirect' => 'Posts pruned. Redirecting …', -'Prune head' => 'Prune', -'Prune subhead' => 'Prune old posts', -'Days old label' => 'Days old', -'Days old help' => 'The number of days "old" a topic must be to be pruned. E.g. if you were to enter 30, every topic that didn\'t contain a post dated less than 30 days old would be deleted.', -'Prune sticky label' => 'Prune sticky topics', -'Prune sticky help' => 'When enabled sticky topics will also be pruned.', -'Prune from label' => 'Prune from forum', -'All forums' => 'All forums', -'Prune from help' => 'The forum from which you want to prune posts.', -'Prune info' => 'Use this feature with caution. Pruned posts can never be recovered. For best performance, you should put the forum in %s during pruning.', -'Confirm prune subhead' => 'Confirm prune posts', -'Confirm prune info' => 'Are you sure that you want to prune all topics older than %s days from %s (%s topics).', -'Confirm prune warn' => 'WARNING! Pruning posts deletes them permanently.', - -); diff --git a/upload/lang/English/admin_ranks.php b/upload/lang/English/admin_ranks.php deleted file mode 100644 index 7dca408..0000000 --- a/upload/lang/English/admin_ranks.php +++ /dev/null @@ -1,21 +0,0 @@ - 'Minimum posts must be a positive integer value.', -'Dupe min posts message' => 'There is already a rank with a minimun posts value of %s.', -'Must enter title message' => 'You must enter a rank title.', -'Rank added redirect' => 'Rank added. Redirecting …', -'Rank updated redirect' => 'Rank updated. Redirecting …', -'Rank removed redirect' => 'Rank removed. Redirecting …', -'Ranks head' => 'Ranks', -'Add rank subhead' => 'Add rank', -'Add rank info' => 'Enter a rank and the minimum number of posts a user must have made to attain the rank. Different ranks cannot have the same value for minimum posts. If a title is set for a user, the title will be displayed instead of any rank. User ranks must be enabled in %s for this to have any effect.', -'Rank title label' => 'Rank title', -'Minimum posts label' => 'Minimum posts', -'Actions label' => 'Actions', -'Edit remove subhead' => 'Edit/remove ranks', -'No ranks in list' => 'No ranks in list', - -); diff --git a/upload/lang/English/admin_reports.php b/upload/lang/English/admin_reports.php deleted file mode 100644 index f954fff..0000000 --- a/upload/lang/English/admin_reports.php +++ /dev/null @@ -1,21 +0,0 @@ - 'Report zapped. Redirecting …', -'New reports head' => 'New reports', -'Deleted user' => 'Deleted user', -'Deleted' => 'Deleted', -'Report subhead' => 'Reported %s', -'Location seperator' => ' » ', -'Reported by' => 'Reported by %s', -'Reason' => 'Reason', -'Zap' => 'Zap', -'No new reports' => 'There are no new reports.', -'Last 10 head' => '10 last zapped reports', -'NA' => 'N/A', -'Zapped subhead' => 'Zapped %s by %s', -'No zapped reports' => 'There are no zapped reports.', - -); diff --git a/upload/lang/English/admin_users.php b/upload/lang/English/admin_users.php deleted file mode 100644 index 1e21a34..0000000 --- a/upload/lang/English/admin_users.php +++ /dev/null @@ -1,70 +0,0 @@ - 'You entered a non-numeric value into a numeric only column.', -'Invalid date time message' => 'You entered an invalid date/time.', -'Not verified' => 'Not verified', -'User search head' => 'User search', -'User search subhead' => 'Enter search criteria', -'User search info' => 'Search for users in the database. You can enter one or more terms to search for. Wildcards in the form of asterisks (*) are accepted.', -'Username label' => 'Username', -'E-mail address label' => 'Email address', -'Title label' => 'Title', -'Real name label' => 'Real name', -'Website label' => 'Website', -'Jabber label' => 'Jabber', -'ICQ label' => 'ICQ', -'MSN label' => 'MSN Messenger', -'AOL label' => 'AOL IM', -'Yahoo label' => 'Yahoo Messenger', -'Location label' => 'Location', -'Signature label' => 'Signature', -'Admin note label' => 'Admin note', -'Posts more than label' => 'Number of posts greater than', -'Posts less than label' => 'Number of posts less than', -'Last post after label' => 'Last post is after', -'Date help' => '(yyyy-mm-dd hh:mm:ss)', -'Last post before label' => 'Last post is before', -'Registered after label' => 'Registered after', -'Registered before label' => 'Registered before', -'Order by label' => 'Order by', -'Order by username' => 'Username', -'Order by e-mail' => 'Email', -'Order by posts' => 'Number of posts', -'Order by last post' => 'Last post', -'Order by registered' => 'Registered', -'Ascending' => 'Ascending', -'Descending' => 'Descending', -'User group label' => 'User group', -'All groups' => 'All groups', -'Unverified users' => 'Unverified users', -'Submit search' => 'Submit search', -'IP search head' => 'IP search', -'IP search subhead' => 'Enter IP to search for', -'IP address label' => 'IP address', -'IP address help' => 'The IP address to search for in the post database.', -'Find IP address' => 'Find IP address', - -'Results head' => 'Search Results', -'Results username head' => 'Username', -'Results e-mail head' => 'Email', -'Results title head' => 'Title/Status', -'Results posts head' => 'Posts', -'Results admin note head' => 'Admin note', -'Results actions head' => 'Actions', -'Results IP address head' => 'IP address', -'Results last used head' => 'Last used', -'Results times found head' => 'Times found', -'Results action head' => 'Action', -'Results find more link' => 'Find more users for this ip', -'Results no posts found' => 'There are currently no posts by that user in the forum.', -'Bad IP message' => 'The supplied IP address is not correctly formatted.', -'Results view IP link' => 'View IP stats', -'Results show posts link' => 'Show posts', -'Results guest' => 'Guest', -'Results no IP found' => 'The supplied IP address could not be found in the database.', -'No match' => 'No match' - -); diff --git a/upload/lang/English/common.php b/upload/lang/English/common.php deleted file mode 100644 index aaade9a..0000000 --- a/upload/lang/English/common.php +++ /dev/null @@ -1,191 +0,0 @@ - 'ltr', // ltr (Left-To-Right) or rtl (Right-To-Left) -'lang_identifier' => 'en', - -// Number formatting -'lang_decimal_point' => '.', -'lang_thousands_sep' => ',', - -// Notices -'Bad request' => 'Bad request. The link you followed is incorrect or outdated.', -'No view' => 'You do not have permission to view these forums.', -'No permission' => 'You do not have permission to access this page.', -'Bad referrer' => 'Bad HTTP_REFERER. You were referred to this page from an unauthorized source. If the problem persists please make sure that \'Base URL\' is correctly set in Admin/Options and that you are visiting the forum by navigating to that URL. More information regarding the referrer check can be found in the FluxBB documentation.', -'No cookie' => 'You appear to have logged in successfully, however a cookie has not been set. Please check your settings and if applicable, enable cookies for this website.', -'Pun include error' => 'Unable to process user include %s from template %s. There is no such file in %s.', - -// Miscellaneous -'Announcement' => 'Announcement', -'Options' => 'Options', -'Submit' => 'Submit', // "Name" of submit buttons -'Ban message' => 'You are banned from this forum.', -'Ban message 2' => 'The ban expires at the end of', -'Ban message 3' => 'The administrator or moderator that banned you left the following message:', -'Ban message 4' => 'Please direct any inquiries to the forum administrator at', -'Never' => 'Never', -'Today' => 'Today', -'Yesterday' => 'Yesterday', -'Info' => 'Info', // A common table header -'Go back' => 'Go back', -'Maintenance' => 'Maintenance', -'Redirecting' => 'Redirecting', -'Click redirect' => 'Click here if you do not want to wait any longer (or if your browser does not automatically forward you)', -'on' => 'on', // As in "BBCode is on" -'off' => 'off', -'Invalid email' => 'The email address you entered is invalid.', -'Required' => '(Required)', -'required field' => 'is a required field in this form.', // For javascript form validation -'Last post' => 'Last post', -'by' => 'by', // As in last post by someuser -'New posts' => 'New posts', // The link that leads to the first new post -'New posts info' => 'Go to the first new post in this topic.', // The popup text for new posts links -'Username' => 'Username', -'Password' => 'Password', -'Email' => 'Email', -'Send email' => 'Send email', -'Moderated by' => 'Moderated by', -'Registered' => 'Registered', -'Subject' => 'Subject', -'Message' => 'Message', -'Topic' => 'Topic', -'Forum' => 'Forum', -'Posts' => 'Posts', -'Replies' => 'Replies', -'Pages' => 'Pages:', -'Page' => 'Page %s', -'BBCode' => 'BBCode:', // You probably shouldn't change this -'img tag' => '[img] tag:', -'Smilies' => 'Smilies:', -'and' => 'and', -'Image link' => 'image', // This is displayed (i.e. ) instead of images when "Show images" is disabled in the profile -'wrote' => 'wrote:', // For [quote]'s -'Mailer' => 'Mailer', // As in "MyForums Mailer" in the signature of outgoing emails -'Important information' => 'Important information', -'Write message legend' => 'Write your message and submit', -'Previous' => 'Previous', -'Next' => 'Next', -'Spacer' => '…', // Ellipsis for paginate - -// Title -'Title' => 'Title', -'Member' => 'Member', // Default title -'Moderator' => 'Moderator', -'Administrator' => 'Administrator', -'Banned' => 'Banned', -'Guest' => 'Guest', - -// Stuff for include/parser.php -'BBCode error no opening tag' => '[/%1$s] was found without a matching [%1$s]', -'BBCode error invalid nesting' => '[%1$s] was opened within [%2$s], this is not allowed', -'BBCode error invalid self-nesting' => '[%s] was opened within itself, this is not allowed', -'BBCode error no closing tag' => '[%1$s] was found without a matching [/%1$s]', -'BBCode error empty attribute' => '[%s] tag had an empty attribute section', -'BBCode code problem' => 'There is a problem with your [code] tags', -'BBCode list size error' => 'Your list was too long to parse, please make it smaller!', - -// Stuff for the navigator (top of every page) -'Index' => 'Index', -'User list' => 'User list', -'Rules' => 'Rules', -'Search' => 'Search', -'Register' => 'Register', -'Login' => 'Login', -'Not logged in' => 'You are not logged in.', -'Profile' => 'Profile', -'Logout' => 'Logout', -'Logged in as' => 'Logged in as', -'Admin' => 'Administration', -'Last visit' => 'Last visit: %s', -'Show new posts' => 'Show new posts since last visit', -'Mark all as read' => 'Mark all topics as read', -'Mark forum read' => 'Mark this forum as read', -'Title separator' => ' / ', - -// Stuff for the page footer -'Board footer' => 'Board footer', -'Search links' => 'Search links', -'Show recent posts' => 'Show recent posts', -'Show unanswered posts' => 'Show unanswered posts', -'Show your posts' => 'Show your posts', -'Show subscriptions' => 'Show your subscribed topics', -'Jump to' => 'Jump to', -'Go' => ' Go ', // Submit button in forum jump -'Moderate topic' => 'Moderate topic', -'Move topic' => 'Move topic', -'Open topic' => 'Open topic', -'Close topic' => 'Close topic', -'Unstick topic' => 'Unstick topic', -'Stick topic' => 'Stick topic', -'Moderate forum' => 'Moderate forum', -'Powered by' => 'Powered by %s', - -// Debug information -'Debug table' => 'Debug information', -'Querytime' => 'Generated in %1$s seconds, %2$s queries executed', -'Query times' => 'Time (s)', -'Query' => 'Query', -'Total query time' => 'Total query time: %s', - -// Email related notifications -'New user notification' => 'Alert - New registration', -'New user message' => 'User \'%s\' registered in the forums at %s', -'Banned email notification' => 'Alert - Banned email detected', -'Banned email register message' => 'User \'%s\' registered with banned email address: %s', -'Banned email change message' => 'User \'%s\' changed to banned email address: %s', -'Banned email post message' => 'User \'%s\' posted with banned email address: %s', -'Duplicate email notification' => 'Alert - Duplicate email detected', -'Duplicate email register message' => 'User \'%s\' registered with an email address that also belongs to: %s', -'Duplicate email change message' => 'User \'%s\' changed to an email address that also belongs to: %s', -'Report notification' => 'Report(%d) - \'%s\'', -'Report message 1' => 'User \'%s\' has reported the following message: %s', -'Report message 2' => 'Reason: %s', - -'User profile' => 'User profile: %s', -'Post URL' => 'Post URL: %s', -'Email signature' => 'Forum Mailer'."\n".'(Do not reply to this message)', - -// For extern.php RSS feed -'RSS description' => 'The most recent topics at %s.', -'RSS description topic' => 'The most recent posts in %s.', -'RSS reply' => 'Re: ', // The topic subject will be appended to this string (to signify a reply) -'RSS active topics feed' => 'RSS active topics feed', -'Atom active topics feed' => 'Atom active topics feed', -'RSS forum feed' => 'RSS forum feed', -'Atom forum feed' => 'Atom forum feed', -'RSS topic feed' => 'RSS topic feed', -'Atom topic feed' => 'Atom topic feed', - -// Admin related stuff in the header -'New reports' => 'There are new reports', -'Maintenance mode enabled' => 'Maintenance mode is enabled!', - -); diff --git a/upload/lang/English/delete.php b/upload/lang/English/delete.php deleted file mode 100644 index 29f358b..0000000 --- a/upload/lang/English/delete.php +++ /dev/null @@ -1,13 +0,0 @@ - 'Delete post', -'Warning' => 'Warning! If this is the first post in the topic, the whole topic will be deleted.', -'Author' => 'Author: %s', -'Delete' => 'Delete', // The submit button -'Post del redirect' => 'Post deleted. Redirecting …', -'Topic del redirect' => 'Topic deleted. Redirecting …' - -); diff --git a/upload/lang/English/forum.php b/upload/lang/English/forum.php deleted file mode 100644 index 241677f..0000000 --- a/upload/lang/English/forum.php +++ /dev/null @@ -1,13 +0,0 @@ - 'Post new topic', -'Views' => 'Views', -'Moved' => 'Moved:', -'Sticky' => 'Sticky:', -'Closed' => 'Closed:', -'Empty forum' => 'Forum is empty.' - -); diff --git a/upload/lang/English/help.php b/upload/lang/English/help.php deleted file mode 100644 index 2f39682..0000000 --- a/upload/lang/English/help.php +++ /dev/null @@ -1,55 +0,0 @@ - 'Help', -'produces' => 'produces', - -'BBCode' => 'BBCode', -'BBCode info 1' => 'BBCode is a collection of formatting tags that are used to change the look of text in this forum. BBCode is based on the same principal as, and is very similar to, HTML. Below is a list of all the available BBCodes and instructions on how to use them.', -'BBCode info 2' => 'Administrators have the ability to enable or disable BBCode. You can tell if BBCode is enabled or disabled out in the left margin whenever you post a message or edit your signature.', - -'Text style' => 'Text style', -'Text style info' => 'The following tags change the appearance of text:', -'Bold text' => 'Bold text', -'Underlined text' => 'Underlined text', -'Italic text' => 'Italic text', -'Red text' => 'Red text', -'Blue text' => 'Blue text', -'Heading text' => 'Heading text', - -'Links and images' => 'Links and images', -'Links info' => 'You can create links to other documents or to email addresses using the following tags:', -'My email address' => 'My email address', -'Images info' => 'If you want to display an image you can use the img tag. The text appearing after the "=" sign in the opening tag is used for the alt attribute and should be included whenever possible.', - -'Quotes' => 'Quotes', -'Quotes info' => 'If you want to quote someone, you should use the quote tag.', -'Quotes info 2' => 'If you don\'t want to quote anyone in particular, you can use the quote tag without specifying a name.', -'Quote text' => 'This is the text i want to quote.', -'produces quote box' => 'produces a quote box like this:', -'quote note' => 'Note: If a username contains the characters [ or ] you can enclose it in quote marks.', - -'Code' => 'Code', -'Code info' => 'When displaying source code you should make sure that you use the code tag. Text displayed with the code tag will use a monospaced font and will not be affected by other tags.', -'Code text' => 'This is some code.', -'produces code box' => 'produces a code box like this:', - -'Nested tags' => 'Nested tags', -'Nested tags info' => 'BBCode can be nested to create more advanced formatting. For example:', -'Bold, underlined text' => 'Bold, underlined text', - -'Lists' => 'Lists', -'List info' => 'To create a list you can use the list tag. You can create 3 types of lists using the list tag.', -'List text 1' => 'Example list item 1.', -'List text 2' => 'Example list item 2.', -'List text 3' => 'Example list item 3.', -'produces list' => 'produces a bulleted list.', -'produces decimal list' => 'produces a numbered list.', -'produces alpha list' => 'produces an alphabetically labelled list.', - -'Smilies' => 'Smilies', -'Smilies info' => 'If you like (and if it is enabled), the forum can convert a series of smilies to images representations of that smiley. This forum recognizes the following smilies and replaces them with images:' - -); diff --git a/upload/lang/English/index.html b/upload/lang/English/index.html deleted file mode 100644 index 89337b2..0000000 --- a/upload/lang/English/index.html +++ /dev/null @@ -1 +0,0 @@ -.. diff --git a/upload/lang/English/index.php b/upload/lang/English/index.php deleted file mode 100644 index 0ed222a..0000000 --- a/upload/lang/English/index.php +++ /dev/null @@ -1,20 +0,0 @@ - 'Topics', -'Link to' => 'Link to:', // As in "Link to: http://fluxbb.org/" -'Empty board' => 'Board is empty.', -'Newest user' => 'Newest registered user: %s', -'Users online' => 'Registered users online: %s', -'Guests online' => 'Guests online: %s', -'No of users' => 'Total number of registered users: %s', -'No of topics' => 'Total number of topics: %s', -'No of posts' => 'Total number of posts: %s', -'Online' => 'Online:', // As in "Online: User A, User B etc." -'Board info' => 'Board information', -'Board stats' => 'Board statistics', -'User info' => 'User information' - -); diff --git a/upload/lang/English/login.php b/upload/lang/English/login.php deleted file mode 100644 index 244ee06..0000000 --- a/upload/lang/English/login.php +++ /dev/null @@ -1,26 +0,0 @@ - 'Wrong username and/or password.', -'Forgotten pass' => 'Forgotten your password?', -'Login redirect' => 'Logged in successfully. Redirecting …', -'Logout redirect' => 'Logged out. Redirecting …', -'No email match' => 'There is no user registered with the email address', -'Request pass' => 'Request password', -'Request pass legend' => 'Enter the email address with which you registered', -'Request pass info' => 'A new password together with a link to activate the new password will be sent to that address.', -'Not registered' => 'Not registered yet?', -'Login legend' => 'Enter your username and password below', -'Remember me' => 'Log me in automatically each time I visit.', -'Login info' => 'If you have not registered or have forgotten your password click on the appropriate link below.', -'New password errors' => 'Password request error', -'New passworderrors info' => 'The following error needs to be corrected before a new password can be sent:', - -// Forget password mail stuff -'Forget mail' => 'An email has been sent to the specified address with instructions on how to change your password. If it does not arrive you can contact the forum administrator at', -'Email flood' => 'This account has already requested a password reset in the past hour. Please wait a while before requesting a new password again.' - -); diff --git a/upload/lang/English/mail_templates/activate_email.tpl b/upload/lang/English/mail_templates/activate_email.tpl deleted file mode 100644 index f17066f..0000000 --- a/upload/lang/English/mail_templates/activate_email.tpl +++ /dev/null @@ -1,12 +0,0 @@ -Subject: Change email address requested - -Hello , - -You have requested to have a new email address assigned to your account in the discussion forum at . If you didn't request this or if you don't want to change your email address you should just ignore this message. Only if you visit the activation page below will your email address be changed. In order for the activation page to work, you must be logged in to the forum. - -To change your email address, please visit the following page: - - --- - -(Do not reply to this message) diff --git a/upload/lang/English/mail_templates/activate_password.tpl b/upload/lang/English/mail_templates/activate_password.tpl deleted file mode 100644 index 33b2b3e..0000000 --- a/upload/lang/English/mail_templates/activate_password.tpl +++ /dev/null @@ -1,14 +0,0 @@ -Subject: New password requested - -Hello , - -You have requested to have a new password assigned to your account in the discussion forum at . If you didn't request this or if you don't want to change your password you should just ignore this message. Only if you visit the activation page below will your password be changed. - -Your new password is: - -To change your password, please visit the following page: - - --- - -(Do not reply to this message) diff --git a/upload/lang/English/mail_templates/form_email.tpl b/upload/lang/English/mail_templates/form_email.tpl deleted file mode 100644 index b862422..0000000 --- a/upload/lang/English/mail_templates/form_email.tpl +++ /dev/null @@ -1,13 +0,0 @@ -Subject: - - from has sent you a message. You can reply to by replying to this email. - -The message reads as follows: ------------------------------------------------------------------------ - - - ------------------------------------------------------------------------ - --- - diff --git a/upload/lang/English/mail_templates/index.html b/upload/lang/English/mail_templates/index.html deleted file mode 100644 index 89337b2..0000000 --- a/upload/lang/English/mail_templates/index.html +++ /dev/null @@ -1 +0,0 @@ -.. diff --git a/upload/lang/English/mail_templates/new_reply.tpl b/upload/lang/English/mail_templates/new_reply.tpl deleted file mode 100644 index e9dab0b..0000000 --- a/upload/lang/English/mail_templates/new_reply.tpl +++ /dev/null @@ -1,11 +0,0 @@ -Subject: Reply to topic: - - has replied to the topic to which you are subscribed. There may be more new replies, but this is the only notification you will receive until you visit the board again. - -The post is located at - -You can unsubscribe by going to - --- - -(Do not reply to this message) diff --git a/upload/lang/English/mail_templates/new_reply_full.tpl b/upload/lang/English/mail_templates/new_reply_full.tpl deleted file mode 100644 index 7231145..0000000 --- a/upload/lang/English/mail_templates/new_reply_full.tpl +++ /dev/null @@ -1,18 +0,0 @@ -Subject: Reply to topic: - - has replied to the topic to which you are subscribed. There may be more new replies, but this is the only notification you will receive until you visit the board again. - -The message reads as follows: ------------------------------------------------------------------------ - - - ------------------------------------------------------------------------ - -The post is located at - -You can unsubscribe by going to - --- - -(Do not reply to this message) diff --git a/upload/lang/English/mail_templates/welcome.tpl b/upload/lang/English/mail_templates/welcome.tpl deleted file mode 100644 index 0110042..0000000 --- a/upload/lang/English/mail_templates/welcome.tpl +++ /dev/null @@ -1,12 +0,0 @@ -Subject: Welcome to ! - -Thank you for registering in the forums at . Your account details are: - -Username: -Password: - -Login at to activate the account. - --- - -(Do not reply to this message) diff --git a/upload/lang/English/misc.php b/upload/lang/English/misc.php deleted file mode 100644 index 9ccd4b2..0000000 --- a/upload/lang/English/misc.php +++ /dev/null @@ -1,90 +0,0 @@ - 'All topics and forums have been marked as read. Redirecting …', -'Mark forum read redirect' => 'All topics in the specified forum have been marked as read. Redirecting …', - -// Send email -'Form email disabled' => 'The user you are trying to send an email to has disabled form email.', -'No email subject' => 'You must enter a subject.', -'No email message' => 'You must enter a message.', -'Too long email message' => 'Messages cannot be longer than 65535 characters (64 KB).', -'Email flood' => 'At least %s seconds have to pass between sent emails. Please wait a while and try sending again.', -'Email sent redirect' => 'Email sent. Redirecting …', -'Send email to' => 'Send email to', -'Email subject' => 'Subject', -'Email message' => 'Message', -'Email disclosure note' => 'Please note that by using this form, your email address will be disclosed to the recipient.', -'Write email' => 'Write and submit your email message', - -// Report -'No reason' => 'You must enter a reason.', -'Report flood' => 'At least %s seconds have to pass between reports. Please wait a while and try sending again.', -'Report redirect' => 'Post reported. Redirecting …', -'Report post' => 'Report post', -'Reason' => 'Reason', -'Reason desc' => 'Please enter a short reason why you are reporting this post', - -// Subscriptions -'Already subscribed' => 'You are already subscribed to this topic.', -'Subscribe redirect' => 'Your subscription has been added. Redirecting …', -'Not subscribed' => 'You are not subscribed to this topic.', -'Unsubscribe redirect' => 'Your subscription has been removed. Redirecting …', - -// General forum and topic moderation -'Moderate' => 'Moderate', -'Select' => 'Select', // the header of a column of checkboxes -'Move' => 'Move', -'Split' => 'Split', -'Delete' => 'Delete', -'Merge' => 'Merge', - -// Moderate forum -'Open' => 'Open', -'Close' => 'Close', -'Move topic' => 'Move topic', -'Move topics' => 'Move topics', -'Move legend' => 'Select destination of move', -'Move to' => 'Move to', -'Nowhere to move' => 'There are no forums into which you can move topics.', -'Leave redirect' => 'Leave redirect topic(s)', -'Move topic redirect' => 'Topic moved. Redirecting …', -'Move topics redirect' => 'Topics moved. Redirecting …', -'Confirm delete legend' => 'Please confirm deletion', -'Delete topics' => 'Delete topics', -'Delete topics comply' => 'Are you sure you want to delete the selected topics?', -'Delete topics redirect' => 'Topics deleted. Redirecting …', -'Open topic redirect' => 'Topic opened. Redirecting …', -'Open topics redirect' => 'Topics opened. Redirecting …', -'Close topic redirect' => 'Topic closed. Redirecting …', -'Close topics redirect' => 'Topics closed. Redirecting …', -'No topics selected' => 'You must select at least one topic for move/delete/open/close.', -'Not enough topics selected' => 'You must select at least two topics for merge.', -'Stick topic redirect' => 'Topic sticked. Redirecting …', -'Unstick topic redirect' => 'Topic unsticked. Redirecting …', -'Merge topics' => 'Merge topics', -'Merge topics redirect' => 'Topics merged. Redirecting …', -'Confirm merge legend' => 'Please confirm merge', -'New subject' => 'New subject', - -// Split multiple posts in topic -'Confirm split legend' => 'Please confirm split of selected posts.', -'Split posts' => 'Split posts', -'Split posts comply' => 'Are you sure you want to split the selected posts?', -'Split posts redirect' => 'Posts have been split. Redirecting …', - -// Delete multiple posts in topic -'Delete posts' => 'Delete posts', -'Cannot select first' => 'First post cannot be selected for split/delete.', -'Delete posts comply' => 'Are you sure you want to delete the selected posts?', -'Delete posts redirect' => 'Posts deleted. Redirecting …', -'No posts selected' => 'You must select at least one post for split/delete.', - -// Get host -'Host info 1' => 'The IP address is: %s', -'Host info 2' => 'The host name is: %s', -'Show more users' => 'Show more users for this IP', - -); diff --git a/upload/lang/English/post.php b/upload/lang/English/post.php deleted file mode 100644 index 5c8ea37..0000000 --- a/upload/lang/English/post.php +++ /dev/null @@ -1,36 +0,0 @@ - 'Topics must contain a subject.', -'Too long subject' => 'Subjects cannot be longer than 70 characters.', -'No message' => 'You must enter a message.', -'Too long message' => 'Posts cannot be longer that 65535 characters (64 KB).', -'All caps subject' => 'Subjects cannot contain only capital letters.', -'All caps message' => 'Posts cannot contain only capital letters.', - -// Posting -'Post errors' => 'Post errors', -'Post errors info' => 'The following errors need to be corrected before the message can be posted:', -'Post preview' => 'Post preview', -'Guest name' => 'Name', // For guests (instead of Username) -'Post redirect' => 'Post entered. Redirecting …', -'Post a reply' => 'Post a reply', -'Post new topic' => 'Post new topic', -'Hide smilies' => 'Never show smilies as icons for this post', -'Subscribe' => 'Subscribe to this topic', -'Stay subscribed' => 'Stay subscribed to this topic', -'Topic review' => 'Topic review (newest first)', -'Flood start' => 'At least', -'flood end' => 'seconds have to pass between posts. Please wait a little while and try posting again.', -'Preview' => 'Preview', // submit button to preview message - -// Edit post -'Edit post legend' => 'Edit the post and submit changes', -'Silent edit' => 'Silent edit (don\'t display "Edited by ..." in topic view)', -'Edit post' => 'Edit post', -'Edit redirect' => 'Post updated. Redirecting …' - -); diff --git a/upload/lang/English/prof_reg.php b/upload/lang/English/prof_reg.php deleted file mode 100644 index 9a69b41..0000000 --- a/upload/lang/English/prof_reg.php +++ /dev/null @@ -1,81 +0,0 @@ - 'Enter a valid email address', -'Email legend 2' => 'Enter and confirm a valid email address', -'Localisation legend' => 'Set your localisation options', -'Time zone' => 'Time zone', -'Time zone info' => 'For the forum to display times correctly you must select your local time zone. If Daylight Savings Time is in effect you should also check the option provided which will advance times by 1 hour.', -'DST' => 'Daylight Savings Time is in effect (advance time by 1 hour).', -'Time format' => 'Time format', -'Date format' => 'Date format', -'Default' => 'Default', -'Language' => 'Language', -'Email setting info' => 'Select whether you want your email address to be viewable to other users or not and if you want other users to be able to send you email via the forum (form email) or not.', -'Email setting 1' => 'Display your email address.', -'Email setting 2' => 'Hide your email address but allow form email.', -'Email setting 3' => 'Hide your email address and disallow form email.', -'Privacy options legend' => 'Set your privacy options', -'Confirm pass' => 'Confirm password', - -'Username too short' => 'Usernames must be at least 2 characters long. Please choose another (longer) username.', -'Username too long' => 'Usernames must not be more than 25 characters long. Please choose another (shorter) username.', -'Username guest' => 'The username guest is reserved. Please choose another username.', -'Username IP' => 'Usernames may not be in the form of an IP address. Please choose another username.', -'Username reserved chars' => 'Usernames may not contain all the characters \', " and [ or ] at once. Please choose another username.', -'Username BBCode' => 'Usernames may not contain any of the text formatting tags (BBCode) that the forum uses. Please choose another username.', -'Banned username' => 'The username you entered is banned in this forum. Please choose another username.', -'Pass too short' => 'Passwords must be at least 4 characters long. Please choose another (longer) password.', -'Pass not match' => 'Passwords do not match.', -'Banned email' => 'The email address you entered is banned in this forum. Please choose another email address.', -'Dupe email' => 'Someone else is already registered with that email address. Please choose another email address.', -'Sig too long' => 'Signatures cannot be longer than', -'characters' => 'characters', -'Sig too many lines' => 'Signatures cannot have more than', -'lines' => 'lines', -'Bad ICQ' => 'You entered an invalid ICQ UIN. Please go back and correct.', - -'UTC-12:00' => '(UTC-12:00) International Date Line West', -'UTC-11:00' => '(UTC-11:00) Niue, Samoa', -'UTC-10:00' => '(UTC-10:00) Hawaii-Aleutian, Cook Island', -'UTC-09:30' => '(UTC-09:30) Marquesas Islands', -'UTC-09:00' => '(UTC-09:00) Alaska, Gambier Island', -'UTC-08:30' => '(UTC-08:30) Pitcairn Islands', -'UTC-08:00' => '(UTC-08:00) Pacific', -'UTC-07:00' => '(UTC-07:00) Mountain', -'UTC-06:00' => '(UTC-06:00) Central', -'UTC-05:00' => '(UTC-05:00) Eastern', -'UTC-04:00' => '(UTC-04:00) Atlantic', -'UTC-03:30' => '(UTC-03:30) Newfoundland', -'UTC-03:00' => '(UTC-03:00) Amazon, Central Greenland', -'UTC-02:00' => '(UTC-02:00) Mid-Atlantic', -'UTC-01:00' => '(UTC-01:00) Azores, Cape Verde, Eastern Greenland', -'UTC' => '(UTC) Western European, Greenwich', -'UTC+01:00' => '(UTC+01:00) Central European, West African', -'UTC+02:00' => '(UTC+02:00) Eastern European, Central African', -'UTC+03:00' => '(UTC+03:00) Moscow, Eastern African', -'UTC+03:30' => '(UTC+03:30) Iran', -'UTC+04:00' => '(UTC+04:00) Gulf, Samara', -'UTC+04:30' => '(UTC+04:30) Afghanistan', -'UTC+05:00' => '(UTC+05:00) Pakistan, Yekaterinburg', -'UTC+05:30' => '(UTC+05:30) India, Sri Lanka', -'UTC+05:45' => '(UTC+05:45) Nepal', -'UTC+06:00' => '(UTC+06:00) Bangladesh, Bhutan, Novosibirsk', -'UTC+06:30' => '(UTC+06:30) Cocos Islands, Myanmar', -'UTC+07:00' => '(UTC+07:00) Indochina, Krasnoyarsk', -'UTC+08:00' => '(UTC+08:00) Greater China, Australian Western, Irkutsk', -'UTC+08:45' => '(UTC+08:45) Southeastern Western Australia', -'UTC+09:00' => '(UTC+09:00) Japan, Korea, Chita', -'UTC+09:30' => '(UTC+09:30) Australian Central', -'UTC+10:00' => '(UTC+10:00) Australian Eastern, Vladivostok', -'UTC+10:30' => '(UTC+10:30) Lord Howe', -'UTC+11:00' => '(UTC+11:00) Solomon Island, Magadan', -'UTC+11:30' => '(UTC+11:30) Norfolk Island', -'UTC+12:00' => '(UTC+12:00) New Zealand, Fiji, Kamchatka', -'UTC+12:45' => '(UTC+12:45) Chatham Islands', -'UTC+13:00' => '(UTC+13:00) Tonga, Phoenix Islands', -'UTC+14:00' => '(UTC+14:00) Line Islands' - -); diff --git a/upload/lang/English/profile.php b/upload/lang/English/profile.php deleted file mode 100644 index ef6a98c..0000000 --- a/upload/lang/English/profile.php +++ /dev/null @@ -1,140 +0,0 @@ - 'Profile menu', -'Section essentials' => 'Essentials', -'Section personal' => 'Personal', -'Section messaging' => 'Messaging', -'Section personality' => 'Personality', -'Section display' => 'Display', -'Section privacy' => 'Privacy', -'Section admin' => 'Administration', - -// Miscellaneous -'Username and pass legend' => 'Enter your username and password', -'Personal details legend' => 'Enter your personal details', -'Contact details legend' => 'Enter your messaging details', -'User activity' => 'User activity', -'Paginate info' => 'Enter the number of topics and posts you wish to view on each page.', - -// Password stuff -'Pass key bad' => 'The specified password activation key was incorrect or has expired. Please re-request a new password. If that fails, contact the forum administrator at', -'Pass updated' => 'Your password has been updated. You can now login with your new password.', -'Pass updated redirect' => 'Password updated. Redirecting …', -'Wrong pass' => 'Wrong old password.', -'Change pass' => 'Change password', -'Change pass legend' => 'Enter and confirm your new password', -'Old pass' => 'Old password', -'New pass' => 'New password', -'Confirm new pass' => 'Confirm new password', -'Pass info' => 'Passwords must be at least 4 characters long. Passwords are case sensitive.', - -// Email stuff -'Email key bad' => 'The specified email activation key was incorrect or has expired. Please re-request change of email address. If that fails, contact the forum administrator at', -'Email updated' => 'Your email address has been updated.', -'Activate email sent' => 'An email has been sent to the specified address with instructions on how to activate the new email address. If it doesn\'t arrive you can contact the forum administrator at', -'Email legend' => 'Enter your new email address', -'Email instructions' => 'An email will be sent to your new address with an activation link. You must click the link in the email you receive to activate the new address.', -'Change email' => 'Change email address', -'New email' => 'New email', - -// Avatar upload stuff -'Avatars disabled' => 'The administrator has disabled avatar support.', -'Too large ini' => 'The selected file was too large to upload. The server didn\'t allow the upload.', -'Partial upload' => 'The selected file was only partially uploaded. Please try again.', -'No tmp directory' => 'PHP was unable to save the uploaded file to a temporary location.', -'No file' => 'You did not select a file for upload.', -'Bad type' => 'The file you tried to upload is not of an allowed type. Allowed types are gif, jpeg and png.', -'Too wide or high' => 'The file you tried to upload is wider and/or higher than the maximum allowed', -'Too large' => 'The file you tried to upload is larger than the maximum allowed', -'pixels' => 'pixels', -'bytes' => 'bytes', -'Move failed' => 'The server was unable to save the uploaded file. Please contact the forum administrator at', -'Unknown failure' => 'An unknown error occurred. Please try again.', -'Avatar upload redirect' => 'Avatar uploaded. Redirecting …', -'Avatar deleted redirect' => 'Avatar deleted. Redirecting …', -'Avatar desc' => 'An avatar is a small image that will be displayed under your username in your posts. It must not be any bigger than', -'Upload avatar' => 'Upload avatar', -'Upload avatar legend' => 'Enter an avatar file to upload', -'Delete avatar' => 'Delete avatar', // only for admins -'File' => 'File', -'Upload' => 'Upload', // submit button - -// Form validation stuff -'Forbidden title' => 'The title you entered contains a forbidden word. You must choose a different title.', -'Profile redirect' => 'Profile updated. Redirecting …', - -// Profile display stuff -'Users profile' => '%s\'s profile', -'Unknown' => '(Unknown)', // This is displayed when a user hasn't filled out profile field (e.g. Location) -'Private' => '(Private)', // This is displayed when a user does not want to receive emails -'No avatar' => '(No avatar)', -'Username info' => 'Username: %s', -'Email info' => 'Email: %s', -'Posts info' => 'Posts: %s', -'Registered info' => 'Registered: %s', -'Last post info' => 'Last post: %s', -'Show posts' => 'Show all posts', -'Realname' => 'Real name', -'Location' => 'Location', -'Website' => 'Website', -'Jabber' => 'Jabber', -'ICQ' => 'ICQ', -'MSN' => 'MSN Messenger', -'AOL IM' => 'AOL IM', -'Yahoo' => 'Yahoo! Messenger', -'Avatar' => 'Avatar', -'Signature' => 'Signature', -'Sig max size' => 'Max length: %s characters / Max lines: %s', -'Avatar legend' => 'Set your avatar display options', -'Avatar info' => 'An avatar is a small image that will be displayed with all your posts. You can upload an avatar by clicking the link below.', -'Change avatar' => 'Change avatar', -'Signature legend' => 'Compose your signature', -'Signature info' => 'A signature is a small piece of text that is attached to your posts. In it, you can enter just about anything you like. Perhaps you would like to enter your favourite quote or your star sign. It\'s up to you! In your signature you can use BBCode if it is allowed in this particular forum. You can see the features that are allowed/enabled listed below whenever you edit your signature.', -'Sig preview' => 'Current signature preview:', -'No sig' => 'No signature currently stored in profile.', -'Signature quote/code/list/h' => 'The quote, code, list, and heading BBCodes are not allowed in signatures.', -'Topics per page' => 'Topics', -'Posts per page' => 'Posts', -'Leave blank' => 'Leave blank to use forum default.', -'Subscription legend' => 'Set your subscription options', -'Notify full' => 'Include a plain text version of new posts in subscription notification emails.', -'Auto notify full' => 'Automatically subscribe to every topic you post in.', -'Show smilies' => 'Show smilies as graphic icons.', -'Show images' => 'Show images in posts.', -'Show images sigs' => 'Show images in user signatures.', -'Show avatars' => 'Show user avatars in posts.', -'Show sigs' => 'Show user signatures.', -'Style legend' => 'Select your preferred style', -'Styles' => 'Styles', -'Admin note' => 'Admin note', -'Pagination legend' => 'Enter your pagination options', -'Post display legend' => 'Set your options for viewing posts', -'Post display info' => 'If you are on a slow connection, disabling these options, particularly showing images in posts and signatures, will make pages load faster.', -'Instructions' => 'When you update your profile, you will be redirected back to this page.', - -// Administration stuff -'Group membership legend' => 'Choose user group', -'Save' => 'Save', -'Set mods legend' => 'Set moderator access', -'Moderator in info' => 'Choose which forums this user should be allowed to moderate. Note: This only applies to moderators. Administrators always have full permissions in all forums.', -'Update forums' => 'Update forums', -'Delete ban legend' => 'Delete (administrators only) or ban user', -'Delete user' => 'Delete user', -'Ban user' => 'Ban user', -'Confirm delete legend' => 'Important: read before deleting user', -'Confirm delete user' => 'Confirm delete user', -'Confirmation info' => 'Please confirm that you want to delete the user', // the username will be appended to this string -'Delete warning' => 'Warning! Deleted users and/or posts cannot be restored. If you choose not to delete the posts made by this user, the posts can only be deleted manually at a later time.', -'Delete posts' => 'Delete any posts and topics this user has made.', -'Delete' => 'Delete', // submit button (confirm user delete) -'User delete redirect' => 'User deleted. Redirecting …', -'Group membership redirect' => 'Group membership saved. Redirecting …', -'Update forums redirect' => 'Forum moderator rights updated. Redirecting …', -'Ban redirect' => 'Redirecting …', -'No delete admin message' => 'Administrators cannot be deleted. In order to delete this user, you must first move him/her to a different user group.', - -); diff --git a/upload/lang/English/register.php b/upload/lang/English/register.php deleted file mode 100644 index c3e24df..0000000 --- a/upload/lang/English/register.php +++ /dev/null @@ -1,37 +0,0 @@ - 'This forum is not accepting new registrations.', -'Reg cancel redirect' => 'Registration cancelled. Redirecting …', -'Forum rules' => 'Forum rules', -'Rules legend' => 'You must agree to the following in order to register', -'Registration flood' => 'A new user was registered with the same IP address as you within the last hour. To prevent registration flooding, at least an hour has to pass between registrations from the same IP. Sorry for the inconvenience.', -'Agree' => 'Agree', -'Cancel' => 'Cancel', -'Register' => 'Register', - -// Form validation stuff (some of these are also used in post.php) -'Registration errors' => 'Registration errors', -'Registration errors info' => 'The following errors need to be corrected before you can register:', -'Username censor' => 'The username you entered contains one or more censored words. Please choose a different username.', -'Username dupe 1' => 'Someone is already registered with the username', -'Username dupe 2' => 'The username you entered is too similar. The username must differ from that by at least one alphanumerical character (a-z or 0-9). Please choose a different username.', -'Email not match' => 'Email addresses do not match.', - -// Registration email stuff -'Reg email' => 'Thank you for registering. Your password has been sent to the specified address. If it doesn\'t arrive you can contact the forum administrator at', -'Reg complete' => 'Registration complete. Logging in and redirecting …', - -// Register info -'Desc 1' => 'Registration will grant you access to a number of features and capabilities otherwise unavailable. These functions include the ability to edit and delete posts, design your own signature that accompanies your posts and much more. If you have any questions regarding this forum you should ask an administrator.', -'Desc 2' => 'Below is a form you must fill out in order to register. Once you are registered you should visit your profile and review the different settings you can change. The fields below only make up a small part of all the settings you can alter in your profile.', -'Username legend' => 'Please enter a username between 2 and 25 characters long', -'Pass legend' => 'Please enter and confirm your chosen password', -'Pass info' => 'Passwords must be at least 4 characters long. Passwords are case sensitive.', -'Email info' => 'You must enter a valid email address as your randomly generated password will be sent to that address.', -'Confirm email' => 'Confirm email address', - -); diff --git a/upload/lang/English/search.php b/upload/lang/English/search.php deleted file mode 100644 index d6a5081..0000000 --- a/upload/lang/English/search.php +++ /dev/null @@ -1,49 +0,0 @@ - 'User search', -'No search permission' => 'You do not have permission to use the search feature.', -'Search flood' => 'At least %s seconds have to pass between searches. Please wait a while and try searching again.', -'Search' => 'Search', -'Search criteria legend' => 'Enter your search criteria', -'Search info' => 'To search by keyword, enter a term or terms to search for. Separate terms with spaces. Use AND, OR and NOT to refine your search. To search by author enter the username of the author whose posts you wish to search for. Use wildcard character * for partial matches.', -'Keyword search' => 'Keyword search', -'Author search' => 'Author search', -'Search in legend' => 'Select where to search', -'Search in info' => 'Choose in which forum you would