From 0e822075512834021658ab3d39165b1974dde57d Mon Sep 17 00:00:00 2001 From: Ahmed Kawa <90964275+Axmaw98@users.noreply.github.com> Date: Fri, 18 Aug 2023 06:53:04 +0300 Subject: [PATCH] Add files via upload --- admin_bans.php | 290 +++++++ admin_categories.php | 221 +++++ admin_censoring.php | 148 ++++ admin_forums.php | 299 +++++++ admin_index.php | 142 ++++ admin_maintenance.php | 169 ++++ admin_options.php | 426 ++++++++++ admin_permissions.php | 205 +++++ admin_prune.php | 220 +++++ admin_ranks.php | 156 ++++ admin_reports.php | 146 ++++ admin_users.php | 490 +++++++++++ delete.php | 176 ++++ docs/COPYING | 340 ++++++++ docs/example_config.php | 21 + docs/install.html | 105 +++ edit.php | 218 +++++ extra/10_rc2_to_10_update.php | 129 +++ extra/prune_unvalidated_users.php | 43 + extra/turn_off_maintenance_mode.php | 46 ++ footer.php | 170 ++++ header.php | 166 ++++ help.php | 132 +++ img/Cobalt_new.png | Bin 0 -> 245 bytes img/Lithium_new.png | Bin 0 -> 245 bytes img/Mercury_new.png | Bin 0 -> 245 bytes img/Oxygen_new.png | Bin 0 -> 245 bytes img/Radium_new.png | Bin 0 -> 245 bytes img/Sulfur_new.png | Bin 0 -> 245 bytes img/avatars/index.html | 8 + img/index.html | 8 + img/smilies/big_smile.png | Bin 0 -> 401 bytes img/smilies/index.html | 8 + img/smilies/mad.png | Bin 0 -> 417 bytes img/smilies/roll.png | Bin 0 -> 440 bytes img/smilies/sad.png | Bin 0 -> 425 bytes img/smilies/smile.png | Bin 0 -> 420 bytes img/smilies/wink.png | Bin 0 -> 416 bytes include/common.php | 815 ++++++++++++++++++ include/commonadmin.php | 119 +++ include/dblayer/commondb.php | 48 ++ include/dblayer/index.html | 8 + include/dblayer/mysql.php | 201 +++++ include/dblayer/pgsql.php | 306 +++++++ include/email.php | 157 ++++ include/index.html | 8 + include/parser.php | 385 +++++++++ include/searchidx.php | 225 +++++ include/template/index.html | 8 + include/template/main.tpl | 30 + include/template/maintenance.tpl | 20 + include/template/redirect.tpl | 22 + index.php | 235 ++++++ install.php | 1060 ++++++++++++++++++++++++ lang/en/en_common.php | 99 +++ lang/en/en_delete.php | 12 + lang/en/en_edit.php | 21 + lang/en/en_forum.php | 14 + lang/en/en_help.php | 41 + lang/en/en_index.php | 29 + lang/en/en_login.php | 28 + lang/en/en_misc.php | 17 + lang/en/en_post.php | 34 + lang/en/en_prof_reg.php | 32 + lang/en/en_profile.php | 115 +++ lang/en/en_register.php | 42 + lang/en/en_search.php | 39 + lang/en/en_stopwords.txt | 151 ++++ lang/en/en_topic.php | 23 + lang/en/en_userlist.php | 12 + lang/en/index.html | 8 + lang/index.html | 8 + login.php | 219 +++++ misc.php | 220 +++++ moderate.php | 261 ++++++ post.php | 514 ++++++++++++ profile.php | 1187 +++++++++++++++++++++++++++ register.php | 343 ++++++++ search.php | 719 ++++++++++++++++ style/Cobalt.css | 101 +++ style/Lithium.css | 99 +++ style/Mercury.css | 102 +++ style/Oxygen.css | 100 +++ style/Radium.css | 101 +++ style/Sulfur.css | 99 +++ style/index.html | 8 + userlist.php | 197 +++++ viewforum.php | 237 ++++++ viewtopic.php | 451 ++++++++++ 89 files changed, 13812 insertions(+) create mode 100644 admin_bans.php create mode 100644 admin_categories.php create mode 100644 admin_censoring.php create mode 100644 admin_forums.php create mode 100644 admin_index.php create mode 100644 admin_maintenance.php create mode 100644 admin_options.php create mode 100644 admin_permissions.php create mode 100644 admin_prune.php create mode 100644 admin_ranks.php create mode 100644 admin_reports.php create mode 100644 admin_users.php create mode 100644 delete.php create mode 100644 docs/COPYING create mode 100644 docs/example_config.php create mode 100644 docs/install.html create mode 100644 edit.php create mode 100644 extra/10_rc2_to_10_update.php create mode 100644 extra/prune_unvalidated_users.php create mode 100644 extra/turn_off_maintenance_mode.php create mode 100644 footer.php create mode 100644 header.php create mode 100644 help.php create mode 100644 img/Cobalt_new.png create mode 100644 img/Lithium_new.png create mode 100644 img/Mercury_new.png create mode 100644 img/Oxygen_new.png create mode 100644 img/Radium_new.png create mode 100644 img/Sulfur_new.png create mode 100644 img/avatars/index.html create mode 100644 img/index.html create mode 100644 img/smilies/big_smile.png create mode 100644 img/smilies/index.html create mode 100644 img/smilies/mad.png create mode 100644 img/smilies/roll.png create mode 100644 img/smilies/sad.png create mode 100644 img/smilies/smile.png create mode 100644 img/smilies/wink.png create mode 100644 include/common.php create mode 100644 include/commonadmin.php create mode 100644 include/dblayer/commondb.php create mode 100644 include/dblayer/index.html create mode 100644 include/dblayer/mysql.php create mode 100644 include/dblayer/pgsql.php create mode 100644 include/email.php create mode 100644 include/index.html create mode 100644 include/parser.php create mode 100644 include/searchidx.php create mode 100644 include/template/index.html create mode 100644 include/template/main.tpl create mode 100644 include/template/maintenance.tpl create mode 100644 include/template/redirect.tpl create mode 100644 index.php create mode 100644 install.php create mode 100644 lang/en/en_common.php create mode 100644 lang/en/en_delete.php create mode 100644 lang/en/en_edit.php create mode 100644 lang/en/en_forum.php create mode 100644 lang/en/en_help.php create mode 100644 lang/en/en_index.php create mode 100644 lang/en/en_login.php create mode 100644 lang/en/en_misc.php create mode 100644 lang/en/en_post.php create mode 100644 lang/en/en_prof_reg.php create mode 100644 lang/en/en_profile.php create mode 100644 lang/en/en_register.php create mode 100644 lang/en/en_search.php create mode 100644 lang/en/en_stopwords.txt create mode 100644 lang/en/en_topic.php create mode 100644 lang/en/en_userlist.php create mode 100644 lang/en/index.html create mode 100644 lang/index.html create mode 100644 login.php create mode 100644 misc.php create mode 100644 moderate.php create mode 100644 post.php create mode 100644 profile.php create mode 100644 register.php create mode 100644 search.php create mode 100644 style/Cobalt.css create mode 100644 style/Lithium.css create mode 100644 style/Mercury.css create mode 100644 style/Oxygen.css create mode 100644 style/Radium.css create mode 100644 style/Sulfur.css create mode 100644 style/index.html create mode 100644 userlist.php create mode 100644 viewforum.php create mode 100644 viewtopic.php diff --git a/admin_bans.php b/admin_bans.php new file mode 100644 index 0000000..76e626c --- /dev/null +++ b/admin_bans.php @@ -0,0 +1,290 @@ +query('SELECT username, email FROM '.$db->prefix.'users WHERE id='.$ban_id) or error('Unable to fetch user info', __FILE__, __LINE__, $db->error()); + if ($db->num_rows($result)) + { + list($ban_user, $ban_email) = $db->fetch_row($result); + + $result = $db->query('SELECT poster_ip FROM '.$db->prefix.'posts WHERE poster_id='.$ban_id.' ORDER BY posted DESC LIMIT 1') or error('Unable to fetch post info', __FILE__, __LINE__, $db->error()); + if ($db->num_rows($result)) + $ban_ip = $db->result($result, 0); + } + else + message('No user by that ID registered.'); + } + else // Otherwise the username is in POST + { + $ban_user = trim($_POST['new_ban_user']); + + if ($ban_user != '') + { + $result = $db->query('SELECT id, username, email FROM '.$db->prefix.'users WHERE username=\''.escape(strtolower($ban_user)).'\'') or error('Unable to fetch user info', __FILE__, __LINE__, $db->error()); + if ($db->num_rows($result)) + { + list($ban_id, $ban_user, $ban_email) = $db->fetch_row($result); + + $result = $db->query('SELECT poster_ip FROM '.$db->prefix.'posts WHERE poster_id='.$ban_id.' ORDER BY posted DESC LIMIT 1') or error('Unable to fetch post info', __FILE__, __LINE__, $db->error()); + if ($db->num_rows($result)) + $ban_ip = $db->result($result, 0); + } + else + message('No user by that username registered. If you want to add a ban not tied to a specific username just leave the username blank.'); + } + } + + + $page_title = htmlspecialchars($options['board_title']).' / Admin / Bans'; + $form_name = 'bans2'; + $focus_element = 'new_ban_ip'; + require 'header.php'; + + if ($cur_user['status'] > 1) + admin_menu('bans'); + else + moderator_menu('bans'); + + +?> +
+ + + + + + + + + +
Supplement ban with IP and e-mail
IP and e-mail   + + + + + + + + + + + + + + + + + + + + + +
Username
IP
The IP or partiall IP you wish to ban (e.g. 150.11.110.1 or 150.11.110). If an IP is entered already it is the last known IP of this user in the database.here to see IP statistics for this user.' ?>
E-mail/domain
The e-mail or e-mail domain you wish to ban (e.g. someone@somewhere.com or somewhere.com). See option "Allow banned e-mail addresses" in Admin/Options for more info.
Expire date
The date when this ban should be removed (format: yyyy-mm-dd). Leave blank to remove manually.
You should be very careful when banning partial IP's because of the possibility of multiple users matching the same partial IP.
+
+
+ +
 
+query('INSERT INTO '.$db->prefix.'bans (username, ip, email, expire) VALUES('.$ban_user.', '.$ban_ip.', '.$ban_email.', '.$ban_expire.')') or error('Unable to add ban', __FILE__, __LINE__, $db->error()); + + redirect('admin_bans.php', 'Ban added. Redirecting ...'); +} + + +// Update a ban +else if (isset($_POST['update'])) +{ + confirm_referer('admin_bans.php'); + + $id = key($_POST['update']); + + $ban_user = trim($_POST['ban_user'][$id]); + $ban_ip = trim($_POST['ban_ip'][$id]); + $ban_email = trim($_POST['ban_email'][$id]); + $ban_expire = trim($_POST['ban_expire'][$id]); + + if ($ban_user == '' && $ban_ip == '' && $ban_email == '') + message('You must enter eighter a username, an IP address or an e-mail address (at least).'); + + require_once '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('The e-mail address (e.g. user@domain.com) or partial e-mail address domain (e.g. domain.com) you entered is invalid.'); + } + + if ($ban_expire != '' && $ban_expire != 'Never') + { + $ban_expire = strtotime($ban_expire); + + if ($ban_expire == -1 || $ban_expire <= time()) + message('You entered an invalid expire date. The format should be yyyy-mm-dd and the date must be at least one day forward from today.'); + } + else + $ban_expire = 'NULL'; + + $ban_user = ($ban_user != '') ? '\''.escape($ban_user).'\'' : 'NULL'; + $ban_ip = ($ban_ip != '') ? '\''.escape($ban_ip).'\'' : 'NULL'; + $ban_email = ($ban_email != '') ? '\''.escape($ban_email).'\'' : 'NULL'; + + $db->query('UPDATE '.$db->prefix.'bans SET username='.$ban_user.', ip='.$ban_ip.', email='.$ban_email.', expire='.$ban_expire.' WHERE id='.$id) or error('Unable to update ban', __FILE__, __LINE__, $db->error()); + + redirect('admin_bans.php', 'Ban updated. Redirecting ...'); +} + + +// Remove a ban +else if (isset($_POST['remove'])) +{ + confirm_referer('admin_bans.php'); + + $id = key($_POST['remove']); + + $db->query('DELETE FROM '.$db->prefix.'bans WHERE id='.$id) or error('Unable to delete ban', __FILE__, __LINE__, $db->error()); + + redirect('admin_bans.php', 'Ban removed. Redirecting ...'); +} + + +$page_title = htmlspecialchars($options['board_title']).' / Admin / Bans'; +$form_name = 'bans'; +$focus_element = 'new_ban_user'; +require 'header.php'; + +if ($cur_user['status'] > 1) + admin_menu('bans'); +else + moderator_menu('bans'); + +?> +
+ + + + + + + + + + + + +
Bans
Add ban   + + + + + + +
Username
The username to ban (case insensitive). The next page will let you enter a custom IP and e-mail. If you just want to ban a specific IP/IP-range or e-mail just leave it blank.
+
Edit/remove bans   + + + + +
+query('SELECT id, username, ip, email, expire FROM '.$db->prefix.'bans ORDER BY id') or error('Unable to ban list', __FILE__, __LINE__, $db->error()); +if ($db->num_rows($result)) +{ + while ($cur_ban = $db->fetch_assoc($result)) + { + $expire = format_time($cur_ban['expire'], true); + print "\t\t\t\t\t\t\t".'   Username       IP       E-mail       Expire        
'."\n"; + } +} +else + print "\t\t\t\t\t\t\t".'No bans in list.'."\n"; + +?> +
+
+
+ +
 
+query('INSERT INTO '.$db->prefix.'categories (cat_name) VALUES(\''.escape($new_cat_name).'\')') or error('Unable to create category', __FILE__, __LINE__, $db->error()); + + redirect('admin_categories.php', 'Category added. Redirecting ...'); +} + + +else if (isset($_POST['del_cat']) || isset($_POST['comply'])) +{ + confirm_referer('admin_categories.php'); + + $cat_to_delete = intval($_POST['cat_to_delete']); + if (empty($cat_to_delete)) + message($lang_common['Bad request']); + + if (isset($_POST['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 (start transaction) + prune($cur_forum, 1, -1); + + // Delete the forum (end transaction) + $db->query('DELETE FROM '.$db->prefix.'forums WHERE id='.$cur_forum, PUN_TRANS_END) 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 OUTER 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()); + + redirect('admin_categories.php', 'Category deleted. Redirecting ...'); + } + else // If the user hasn't comfirmed the delete + { + $page_title = htmlspecialchars($options['board_title']).' / Admin / Categories'; + require 'header.php'; + + admin_menu('categories'); + +?> +
+ + + + + + + + +
Confirm delete category
+
 Are you sure that you want to delete this category?

+  WARNING! Deleting a category will delete all forums and posts (if any) in that category!

+     Go back

+
+
+ +
 
+query('SELECT id, position FROM '.$db->prefix.'categories ORDER BY 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('You must enter a category name.'); + + if ($cat_order[$i] == '' || preg_match('/[^0-9]/', $cat_order[$i])) + message('Position must be an integer value.'); + + if ($admmod_only[$i] != '1') + $admmod_only[$i] = '0'; + + list($cat_id, $position) = $db->fetch_row($result); + + $db->query('UPDATE '.$db->prefix.'categories SET cat_name=\''.escape($cat_name[$i]).'\', admmod_only=\''.$admmod_only[$i].'\', position='.$cat_order[$i].' WHERE id='.$cat_id) or error('Unable to update category', __FILE__, __LINE__, $db->error()); + } + + redirect('admin_categories.php', 'Category updated. Redirecting ...'); +} + + +// Generate an array with all categories +$result = $db->query('SELECT id, cat_name, admmod_only, position FROM '.$db->prefix.'categories ORDER BY 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 = htmlspecialchars($options['board_title']).' / Admin / Categories'; +require 'header.php'; + +admin_menu('categories'); + +?> +
+ + + + + + + + + + + + + + + + +
Add/remove/edit categories
Edit categories   + +
  Position       Name       > Admins/moderators only + +

  

+
Add a new category   +
 

+   

+
Delete a category   +
 

+   

+
+
+ +
 
+query('INSERT INTO '.$db->prefix.'censoring (search_for, replace_with) VALUES (\''.escape($search_for).'\', \''.escape($replace_with).'\')') or error('Unable to add censor word', __FILE__, __LINE__, $db->error()); + + redirect('admin_censoring.php', 'Censor word added. Redirecting ...'); +} + + +// Update a censor word +else if (isset($_POST['update'])) +{ + confirm_referer('admin_censoring.php'); + + $id = key($_POST['update']); + + $search_for = trim($_POST['search_for'][$id]); + $replace_with = trim($_POST['replace_with'][$id]); + + if ($search_for == '' || $replace_with == '') + message('You must enter both text to search for and text to replace with.'); + + $db->query('UPDATE '.$db->prefix.'censoring SET search_for=\''.escape($search_for).'\', replace_with=\''.escape($replace_with).'\' WHERE id='.$id) or error('Unable to update censor word', __FILE__, __LINE__, $db->error()); + + redirect('admin_censoring.php', 'Censor word updated. Redirecting ...'); +} + + +// Remove a censor word +else if (isset($_POST['remove'])) +{ + confirm_referer('admin_censoring.php'); + + $id = 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', 'Censor word removed. Redirecting ...'); +} + + +$page_title = htmlspecialchars($options['board_title']).' / Admin / Censoring'; +$form_name = 'censoring'; +$focus_element = 'new_search_for'; +require 'header.php'; + +if ($cur_user['status'] > 1) + admin_menu('censoring'); +else + moderator_menu('censoring'); + +?> +
+ + + + + + + + + + + + +
Censoring
Add word   + + + + + + + + + + + + + +
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 Options for this to have any effect.

Word
The word to censor.
Replacement
The text to replace the matching censored word with.
+
Edit/remove words   + + + + +
+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)) +{ + while ($cur_word = $db->fetch_assoc($result)) + print "\t\t\t\t\t\t\t".'   Word       Replacement        
'."\n"; +} +else + print "\t\t\t\t\t\t\t".'No censor 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()); + + redirect('admin_forums.php', 'Forum added. Redirecting ...'); +} + + +// Delete a forum +else if (isset($_POST['del_forum']) || isset($_POST['comply'])) +{ + confirm_referer('admin_forums.php'); + + $forum_to_delete = intval($_POST['forum_to_delete']); + if (empty($forum_to_delete)) + message($lang_common['Bad request']); + + if (isset($_POST['comply'])) // Delete a forum with all posts + { + @set_time_limit(0); + + // Prune all posts and topics (start transaction) + prune($forum_to_delete, 1, -1); + + // Locate any "orphaned redirect topics" and delete them + $result = $db->query('SELECT t1.id FROM '.$db->prefix.'topics AS t1 LEFT OUTER 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 (end transaction) + $db->query('DELETE FROM '.$db->prefix.'forums WHERE id='.$forum_to_delete, PUN_TRANS_END) or error('Unable to delete forum', __FILE__, __LINE__, $db->error()); + + redirect('admin_forums.php', 'Forum deleted. Redirecting ...'); + } + else // If the user hasn't confirmed the delete + { + $page_title = htmlspecialchars($options['board_title']).' / Admin / Forums'; + require 'header.php'; + + admin_menu('forums'); + +?> +
+ + + + + + + + +
Confirm delete forum
+
 Are you sure that you want to delete this forum?

+  WARNING! Deleting a forum will delete all posts (if any) in that forum!

+     Go back

+
+
+ +
 
+query('UPDATE '.$db->prefix.'forums SET forum_name=\''.escape($cur_forum_name).'\', forum_desc='.$cur_forum_desc.', closed=\''.$cur_closed.'\', admmod_only=\''.$cur_admmod_only.'\', position='.$cur_position.', cat_id='.$cur_cat_id.' WHERE id='.$id) or error('Unable to update forum', __FILE__, __LINE__, $db->error()); + } + + redirect('admin_forums.php', 'Forum(s) updated. Redirecting ...'); +} + + +// Generate an array with all forums and their respective category (used frequently) +$result = $db->query('SELECT c.id AS cid, c.cat_name, f.id AS fid, f.forum_name, f.forum_desc, f.closed, f.admmod_only, f.position FROM '.$db->prefix.'categories AS c LEFT JOIN '.$db->prefix.'forums AS f ON c.id=f.cat_id ORDER BY c.position, cid, f.position') or error('Unable to fetch category/forum list', __FILE__, __LINE__, $db->error()); +$num_forums = $db->num_rows($result); + +$forum_list = array(); +while ($num_forums--) + $forum_list[] = $db->fetch_assoc($result); + + +$page_title = htmlspecialchars($options['board_title']).' / Admin / Forums'; +require 'header.php'; + +admin_menu('forums'); + +?> +
+ + + + + + + + +
Add/delete forums
+
  Add forum to category   +   

+
+
  Delete forum   +   

+
+
+ +
 
+ +
+ + + + +'."\n"; + $cur_category = $cur_forum['cid']; + } + + if ($cur_forum['fid'] != '') + { + +?> + + + + + + + +
Edit forums
'.htmlspecialchars($cur_forum['cat_name']).'
+ + + + + + + + + + + + + + + + + + + +
Position Options > Admins/moderators only
Name  > Closed
Description
(HTML)
 Category +   +
+



+
+ +
 
+query('SELECT COUNT(user_id) FROM '.$db->prefix.'online') or error('Unable to fetch online count', __FILE__, __LINE__, $db->error()); +$num_online = $db->result($result, 0); + + +// Get the database system version +$result = $db->query('SELECT version()') or error('Unable to fetch version info', __FILE__, __LINE__, $db->error()); +$db_version = $db->result($result, 0); + + +if ($db_type == 'mysql') +{ + $db_version = 'MySQL '.$db_version; + + // Calculate total db size/row count (MySQL only) + $result = $db->query('SHOW TABLE STATUS FROM '.$db_name) or error('Unable to fetch table status', __FILE__, __LINE__, $db->error()); + $num_tables = $db->num_rows($result); + + $total_records = 0; + $total_size = 0; + while ($num_tables--) + { + $status = $db->fetch_row($result); + $total_records += (int)$status[3]; + $total_size += (int)$status[5] + (int)$status[7]; + } + + + $total_size = $total_size/1024; + + if ($total_size > 1024) + $total_size = round($total_size/1024, 2).' MB'; + else + $total_size = round($total_size, 2).' KB'; +} + + +$page_title = htmlspecialchars($options['board_title']).' / Admin'; +require 'header.php'; + +if ($cur_user['status'] > 1) + admin_menu(); +else + moderator_menu(); + +?> + + + + + + + +
Forum administation
+ Welcome to the PunBB administration control panel. From here you can control vital aspects of the forum. Depending on whether you are an administrator or a moderator you can

+  - organize categories and forums.
+  - set forum-wide options and preferences.
+  - control permissions for users and guests.
+  - view IP statistics for users.
+  - ban users.
+  - censor words.
+  - set up user ranks.
+  - prune old posts.
+  - handle post reports.

+
+ +
 
+ + + + + + + + + + + + + + + + + +
Statistics
Current version   +  PunBB

+  Developed by Rickard Andersson
+  © Copyright 2002, 2003 Rickard Andersson +
Unix load averages    - users online
Environment   +  PHP
+   +

 Rows:
+  Size: + +
+ +
 
+query('TRUNCATE TABLE '.$db->prefix.'search_matches') or error('Unable to empty search index match table', __FILE__, __LINE__, $db->error()); + $db->query('TRUNCATE TABLE '.$db->prefix.'search_words') or error('Unable to empty search index words table', __FILE__, __LINE__, $db->error()); + } + + $end_at = $start_at + $per_page; + +?> + + + + + +<?php print htmlspecialchars($options['board_title']) ?> / Rebuilding search index... + + + + +Rebuilding index... This might be a good time to put on some coffee :-)

+ +query('SELECT DISTINCT t.id, p.id, p.message FROM '.$db->prefix.'topics AS t INNER JOIN '.$db->prefix.'posts AS p ON t.id=p.topic_id WHERE t.id>='.$start_at.' AND t.id<'.$end_at.' ORDER BY t.id') or error('Unable to fetch topic/post info', __FILE__, __LINE__, $db->error()); + + while ($cur_post = $db->fetch_row($result)) + { + if ($cur_post[0] <> $cur_topic) + { + // Fetch subject and ID of first post in topic + $result2 = $db->query('SELECT p.id, t.subject, MIN(p.posted) AS first FROM '.$db->prefix.'posts AS p INNER JOIN '.$db->prefix.'topics AS t ON t.id=p.topic_id WHERE t.id='.$cur_post[0].' GROUP BY p.id, t.subject ORDER BY first LIMIT 1') or error('Unable to fetch topic info', __FILE__, __LINE__, $db->error()); + list($first_post, $subject) = $db->fetch_row($result2); + + $cur_topic = $cur_post[0]; + } + + print 'Processing post '.$cur_post[1].' in topic '.$cur_post[0].'
'."\n"; + flush(); + + if ($cur_post[1] == $first_post) // This is the "topic post" so we have to index the subject as well + update_search_index('post', $cur_post[1], $cur_post[2], $subject); + else + update_search_index('post', $cur_post[1], $cur_post[2]); + } + + // Check if there is more work to do + $result = $db->query('SELECT id FROM '.$db->prefix.'topics WHERE id>'.$end_at) or error('Unable to fetch topic info', __FILE__, __LINE__, $db->error()); + if ($db->num_rows($result)) + print ''; + else + print ''; + + $db->close(); + exit; +} + + +else +{ + // Get the first post ID from the db + $result = $db->query('SELECT id FROM '.$db->prefix.'topics ORDER BY id LIMIT 1') or error('Unable to create category', __FILE__, __LINE__, $db->error()); + if ($db->num_rows($result)) + $first_id = $db->result($result, 0); + + $page_title = htmlspecialchars($options['board_title']).' / Admin / Maintenance'; + $validate_form = true; + $form_name = 'rebuild'; + $focus_element = 'req_per_page'; + require 'header.php'; + + admin_menu('maintenance'); + +?> +
+ + + + + + + + +
Search index
Rebuild search index   + + + + + + + + + + + + + + + + + + + + +
If you switched language while there were posts in the database, you should rebuild the search index (to remove stopwords). For best performance you should put the forum in maintenance mode during rebuilding. Rebuilding the search index can take a long time and will increase server load during the rebuild process!
Topics per cycle
The number of topics to process per pageview. E.g. if you were to enter 100, one hundred topics would be processed and then the page would refresh. This is to prevent the script from timing out during the rebuild process.
Topic ID to start at
The topic ID to start rebuilding at. It's default value is the first available ID in the database. Normally you wouldn't want to change this.
Empty index
Select this if you want the search index to be emptied before rebuilding (see below).
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 after a cycle has completed). If you are forced to abort the rebuild process, make a note of the last processed topic ID and enter that ID+1 in "Topic ID to start at" when/if you want to continue ("Empty index" must not be selected).
+
+
+ +
 
+'.$options['admin_email'].'.'); + + $form = array_map('trim', $_POST['form']); + + if ($form['board_title'] == '') + message('You must enter a board title.'); + + require 'include/email.php'; + + $form['admin_email'] = strtolower($form['admin_email']); + if (!is_valid_email($form['admin_email'])) + message('The admin e-mail address you entered is invalid.'); + + $form['webmaster_email'] = strtolower($form['webmaster_email']); + if (!is_valid_email($form['webmaster_email'])) + message('The webmaster e-mail address you entered is invalid.'); + + if ($form['mailing_list'] != '') + $form['mailing_list'] = strtolower(preg_replace('/[\s]/', '', $form['mailing_list'])); + + // Make sure all newlines are \n and not \r\n or \r + if ($form['rules_message'] != '') + $form['rules_message'] = str_replace("\r", "\n", str_replace("\r\n", "\n", $form['rules_message'])); + + if ($form['rules'] == '1' && $form['rules_message'] == '') + $form['rules'] = '0'; + + // 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); + + // 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['maintenance_message'] != '') + $form['maintenance_message'] = str_replace("\r", "\n", str_replace("\r\n", "\n", $form['maintenance_message'])); + else + $form['maintenance_message'] = 'The forums are temporarily down for maintenance. Please try again in a few minutes.\n\n/Administrator'; + + foreach ($form as $key => $input) + { + $value = ($input != '') ? $value = '\''.escape($input).'\'' : 'NULL'; + $temp[] = $key.'='.$value; + } + + $db->query('UPDATE '.$db->prefix.'options SET '.implode(',', $temp)) or error('Unable to update options', __FILE__, __LINE__, $db->error()); + + redirect('admin_options.php', 'Options updated. Redirecting ...'); +} + + +$page_title = htmlspecialchars($options['board_title']).' / Admin / Options'; +$validate_form = true; +$form_name = 'update_options'; +require 'header.php'; + +admin_menu('options'); + +?> +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Options



Title and description   + + + + + + + + + +
Board title
The title of this bulletin board (shown at the top of every page). This field may not contain HTML.
Board description
A short description of this bulletin board (shown at the top of every page). This field may contain HTML.
+
Time and timeouts   + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Server timezone
The timezone for the server.
+ +
Time format
The format string for representing time. See here for formatting options.
  Current format:
Date format
The format string for representing date. See here for formatting options.
  Current format:
Cookie timeout
Number of seconds to wait before writing a new cookie (primarily affects new message indicators).
Online timeout
Number of seconds a user can be idle before being removed from the online users list.
Redirect time
Number of seconds to wait when redirecting.
Flood interval
Number of seconds that users have to wait between posts. Set to 0 to disable.
+
Display   + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Smilies
Convert a series of smilies to small icons.
> Yes   > No
Smilies in signatures
Convert a series of smilies to small icons in user signatures.
> Yes   > No
Make clickable links
When enabled, PunBB will automatically detect any URL's in posts and make them clickable hyperlinks.
> Yes   > No
Show user post count
Show the number of posts a user has made (affects topic view, profile and userlist).
> Yes   > No
Default style
This is the default style used if the visitor is a guest or a user that hasn't changed from the default in his/her profile.
+ +
Topic review
Maximum number of posts to display when posting (newest first). 0 to disable.
Topics per page default
The default number of topics to display per page in a forum. Users can personalize this setting.
Posts per page default
The default number of posts to display per page in a topic. Users can personalize this setting.
Indent size
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.
+
Features   + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Quick post
When enabled, PunBB will add a quick post form at the bottom of topics. This way users can post directly from the topic view.
> Yes   > No
Users online
Display a list of users current online on the index page.
> Yes   > No
Censor words
Enable this to censor specific words in the forum. See Censoring for more info.
> Yes   > No
User ranks
Enable this to use user ranks. See Ranks for more info.
> Yes   > No
User has posted earlier
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.
> Yes   > No
Quick jump
Enable the quick jump (jump to forum) drop list.
> Yes   > No
GZip output
If enabled, PunBB 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 the Apache module mod_gzip set up to compress PHP scripts, you should disable this feature.
> Yes   > No
+
Reports   + + + + + + + + + +
Report method
Select the method for handling topic/post reports. You can choose whether topic/post reports should be handled by the internal report system, e-mailed to the addresses on the mailing list (see below) or both.
> Internal   > E-mail   > Both
Mailing list
A comma separatad list of subscribers. The people on this list are the recipients of topic/post reports (see above).
+
Avatars   + + + + + + + + + + + + + + + + + + + + + +
Use avatars
When enabled, users will be able to upload an avatar which will be displayed under their title/rank.
> Yes   > No
Upload directory
The upload directory for avatars (relative to the PunBB root directory). PHP must have write permissions to this directory.
Max width
The maximum allowed width of avatars in pixels (60 is recommended).
Max height
The maximum allowed height of avatars in pixels (60 is recommended).
Max size
The maximum allowed size of avatars in bytes (10240 is recommended).
+
Search   + + + + + + + + + +
Search enabled
When disabled, regular users will not be able to use the search feature. "Show new posts since last visit" and "Show posts by this user" will still work though.
> Yes   > No
Search all forums
When disabled, searches will only be allowed in one forum at a time. Disable if server load is high due to excessive searching.
> Yes   > No
+
E-mail   + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Base URL
The complete URL of the forum 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.
Admin e-mail
The e-mail address of the forum administrator.
Webmaster e-mail
This is the address that all e-mails sent by the forum will be addressed from.
Subscriptions
Enable users to subscribe to topics (recieve e-mail when someone replies).
> Yes   > No
SMTP server address
The address of an external SMTP server to send e-mails with. Leave blank to use the local mail program.
SMTP username
Username for SMTP server. Only enter a username if it is required by the SMTP server (most servers don't require authentication).
SMTP password
Password for SMTP server. Only enter a password if it is required by the SMTP server (most servers don't require authentication).
+
Registration   + + + + + + + + + + + + + + + + + +
Allow new registrations
Controls whether this forum accepts new registrations. Disable only under special circumstances.
> Yes   > No
Validate registrations
When enabled, users are e-mailed 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 validate new e-mail 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" e-mail addresses in their profiles.
> Yes   > No
Use forum rules
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.
> Yes   > No
Rules
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.
+
Maintenance   + + + + + + + + + +
Maintenance mode
When enabled, the board will only be available to administrators. This should be used if the board needs to 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.
> Yes   > No
Message
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.
+



+
+ +
 
+ $input) + { + if (trim($input ) != '') + $value = '\''.escape($input).'\''; + else + $value = 'NULL'; + + $temp[] = $key.'='.$value; + } + + $db->query('UPDATE '.$db->prefix.'permissions SET '.implode(',', $temp)) or error('Unable to update permissions', __FILE__, __LINE__, $db->error()); + + redirect('admin_permissions.php', 'Permissions updated. Redirecting ...'); +} + + +$page_title = htmlspecialchars($options['board_title']).' / Admin / Permissions'; +require 'header.php'; +admin_menu('permissions'); + +?> +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Permissions



Guests   + + + + + + + + + + + + + + + + + +
Guests may read forum
Allow guests (not registered users) to read the forum.
> Yes   > No
Guests may post replies
Allow guests (not registered users) to post replies to topics in the forum.
> Yes   > No
Guests may post topics
Allow guests (not registered users) to post new topics.
> Yes   > No
Guests may use search
Allow guests (not registered users) to use the forum search engine.
> Yes   > No
+
Users   + + + + + + + + + + + + + + + + + + + + + + + + + +
Users may post replies
Allow users to post replies to topics in the forum.
> Yes   > No
Users may post topics
Allow users to post new topics.
> Yes   > No
Users may edit posts
Allow users to edit their own posts.
> Yes   > No
Users may delete posts
Allow users to delete their own posts.
> Yes   > No
Users may delete topics
Allow users to delete their own topics.
> Yes   > No
Users may set title
Allow users to set their title.
> Yes   > No
+
Posting   + + + + + + + + + + + + + + + + + + + + + +
HTML
Allow HTML in posts (not recommended).
> Yes   > No
BBCode
Allow BBCode in posts (recommended).
> Yes   > No
Image tag
Allow the BBCode [img][/img] tag in posts.
> Yes   > No
All caps message
Allow a message to contain only capital letters.
> Yes   > No
All caps subject
Allow a subject to contain only capital letters.
> Yes   > No
+
Signatures   + + + + + + + + + + + + + + + + + + + + + + + + + +
HTML in signatures
Allow HTML in user signatures (not recommended).
> Yes   > No
BBCodes in signatures
Allow BBCodes in user signatures.
> Yes   > No
Image tag in signatures
Allow the BBCode [img][/img] tag in user signatures (not recommended).
> Yes   > No
All caps signature
Allow a signature to contain only capital letter.
> Yes   > No
Maximum signature length
The maximum number of characters a user signature may contain.
Maximum signature lines
The maximum number of lines a user signature may contain.
+
Registration   + + + + + + + + + +
Allow banned e-mail addresses
Allow users to register with or change to a banned e-mail address/domain. If left at it's default setting (yes) this action will be allowed, but an alert e-mail will be sent to the mailing list (an effective way of detecting multiple registrations).
> Yes   > No
Allow duplicate e-mail addresses
Controls whether users should be allowed to register with an e-mail address that another user already has. If allowed, an alert e-mail will be sent to the mailing list if a duplicate is detected.
> Yes   > No
+



+
+ +
 
+ 0) ? time() - ($prune_days*86400) : -1; + + @set_time_limit(0); + + if ($prune_from == 'all') + { + $result = $db->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, $_POST['prune_sticky'], $prune_date); // start transaction + update_forum($fid, PUN_TRANS_END); // end transaction + } + } + else + { + prune($prune_from, $_POST['prune_sticky'], $prune_date); // start transaction + update_forum($prune_from, PUN_TRANS_END); // end transaction + } + + // Locate any "orphaned redirect topics" and delete them + $result = $db->query('SELECT t1.id FROM '.$db->prefix.'topics AS t1 LEFT OUTER 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', 'Posts pruned. Redirecting ...'); + } + else + { + $prune_days = $_POST['req_prune_days']; + if (preg_match('/[^0-9]/', $prune_days)) + message('Days to prune must be a positive integer.'); + + $prune_date = time() - ($prune_days*86400); + $prune_from = $_POST['prune_from']; + + // Concatenate together the query for counting number or topics to prune + $sql = 'SELECT COUNT(id) FROM '.$db->prefix.'topics WHERE last_post<'.$prune_date; + + if ($_POST['prune_sticky'] == '0') + $sql .= ' AND sticky=\'0\''; + + if ($prune_from != 'all') + { + $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 = '"'.$db->result($result, 0).'"'; + } + else + $forum = 'all forums'; + + $result = $db->query($sql) or error('Unable to fetch topic prune count', __FILE__, __LINE__, $db->error()); + $num_topics = $db->result($result, 0); + + if (!$num_topics) + message('There are no topics that are '.$prune_days.' days old. Please decrease the value of "Days old" and try again.'); + + + $page_title = htmlspecialchars($options['board_title']).' / Admin / Prune'; + require 'header.php'; + + admin_menu('prune'); + +?> +
+ + + + + + + + + + +
Confirm prune posts
+
 Are you sure that you want to prune all topics older than days from ? ( topics)

+  WARNING! Pruning posts deletes them permanently.

+     Go back

+
+
+ +
 
+ +
+ + + + + + + + + +
Prune old posts
Prune   + + + + + + + + + + + + + + + + + +
Days old
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 from up til 30 days ago would be deleted.
Prune sticky topics
When enabled sticky topics will also be pruned.
 Yes    No
Prune from forum
The forum from which you want to prune posts.
+ +
Use this feature with caution. Pruned posts can never be recovered. For best performance you should put the forum in maintenance mode during pruning.
+
+
+ +
 
+query('SELECT NULL 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('There is already a rank with a minimun posts value of '.$min_posts.'.'); + + $db->query('INSERT INTO '.$db->prefix.'ranks (rank, min_posts) VALUES(\''.escape($rank).'\', '.$min_posts.')') or error('Unable to add rank', __FILE__, __LINE__, $db->error()); + + redirect('admin_ranks.php', 'Rank added. Redirecting ...'); +} + + +// Update a rank +else if (isset($_POST['update'])) +{ + confirm_referer('admin_ranks.php'); + + $id = key($_POST['update']); + + $rank = trim($_POST['rank'][$id]); + $min_posts = trim($_POST['min_posts'][$id]); + + if ($rank == '') + message('You must enter a rank title.'); + + if ($min_posts == '' || preg_match('/[^0-9]/', $min_posts)) + message('Minimum posts must be a positive integer value.'); + + $db->query('UPDATE '.$db->prefix.'ranks SET rank=\''.escape($rank).'\', min_posts='.$min_posts.' WHERE id='.$id) or error('Unable to update rank', __FILE__, __LINE__, $db->error()); + + redirect('admin_ranks.php', 'Rank updated. Redirecting ...'); +} + + +// Remove a rank +else if (isset($_POST['remove'])) +{ + confirm_referer('admin_ranks.php'); + + $id = key($_POST['remove']); + + $db->query('DELETE FROM '.$db->prefix.'ranks WHERE id='.$id) or error('Unable to delete rank', __FILE__, __LINE__, $db->error()); + + redirect('admin_ranks.php', 'Rank removed. Redirecting ...'); +} + + +$page_title = htmlspecialchars($options['board_title']).' / Admin / Ranks'; +$form_name = 'ranks'; +$focus_element = 'new_rank'; +require 'header.php'; + +admin_menu('ranks'); + +?> +
+ + + + + + + + + + + + +
Ranks
Add rank   + + + + + + + + + + + + + +
Enter a rank and the minimum number of posts that a user has to have to aquire 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 Options for this to have any effect.

Rank title
Text to be displayed under username.
Minimum posts
The minimum number of posts a user must have to attain this rank.
+
Edit/remove ranks   + + + + +
+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)) +{ + while ($cur_rank = $db->fetch_assoc($result)) + print "\t\t\t\t\t\t\t".'   Rank title       Minimum posts        
'."\n"; +} +else + print "\t\t\t\t\t\t\t".'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, 0); + + if ($zapped == '') + $db->query('UPDATE '.$db->prefix.'reports SET zapped='.time().', zapped_by='.$cur_user['id'].' WHERE id='.$zap_id) or error('Unable to zap report', __FILE__, __LINE__, $db->error()); + + redirect('admin_reports.php', 'Report zapped. Redirecting ...'); +} + + +$page_title = htmlspecialchars($options['board_title']).' / Admin / Reports'; +require 'header.php'; + +if ($cur_user['status'] > 1) + admin_menu('reports'); +else + moderator_menu('reports'); + + +?> +
+ + + + + + + + + + +query('SELECT r.id, r.post_id, r.topic_id, r.forum_id, r.reported_by, r.created, r.message, t.subject, f.forum_name, u.username AS reporter FROM '.$db->prefix.'reports AS r INNER JOIN '.$db->prefix.'topics AS t ON r.topic_id=t.id INNER 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'] != '') ? ''.htmlspecialchars($cur_report['reporter']).'' : 'N/A'; + +?> + + + + + + + + +'."\n"; + +?> +
New reports
ForumTopicMessageReporterCreatedActions
', htmlspecialchars($cur_report['message'])) ?>
There are no new reports.
+
+ +
 
+ + + + + + + + + + +query('SELECT r.id, r.post_id, r.topic_id, r.forum_id, r.reported_by, r.message, r.zapped, r.zapped_by AS zapped_by_id, t.subject, f.forum_name, u.username AS reporter, u2.username AS zapped_by FROM '.$db->prefix.'reports AS r INNER JOIN '.$db->prefix.'topics AS t ON r.topic_id=t.id INNER 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'] != '') ? ''.htmlspecialchars($cur_report['reporter']).'' : 'N/A'; + $zapped_by = ($cur_report['zapped_by'] != '') ? ''.htmlspecialchars($cur_report['zapped_by']).'' : 'N/A'; + +?> + + + + + + + +'."\n"; + +?> +
10 last zapped reports
ForumTopicMessageReporterZapped
', htmlspecialchars($cur_report['message'])) ?>
There are no zapped reports.
+ +
 
+ 1) + admin_menu('users'); + else + moderator_menu('users'); + +?> + + + + + + + + +query('SELECT poster_ip, posted FROM '.$db->prefix.'posts WHERE poster_id='.$ip_stats.' ORDER BY posted DESC') or error('Unable to fetch post info', __FILE__, __LINE__, $db->error()); + $num_posts = $db->num_rows($result); + + if ($num_posts) + { + // Fetch the first hit and add it to hit_list + $cur_hit = $db->fetch_row($result); + $hit_list = array($cur_hit[0] => array($cur_hit[1], 1)); + + // Loop through hits and update hit_list + for ($i = 1; $i < $num_posts; $i++) + { + $cur_hit = $db->fetch_row($result); + + if (isset($hit_list[$cur_hit[0]])) + { + $hit_list[$cur_hit[0]][1]++; + + if ($cur_hit[1] > $hit_list[$cur_hit[0]][0]) + $hit_list[$cur_hit[0]][0] = $cur_hit[1]; + } + else + $hit_list[$cur_hit[0]] = array($cur_hit[1], 1); + } + + foreach ($hit_list as $key => $value) + { + +?> + + + + + + + +'."\n"; + +?> + +
IP addressHostnameLast usedTimes foundAction
Find more users for this ip
There are currently no posts by that user in the forum.
 
+ 1) + admin_menu('users'); + else + moderator_menu('users'); + +?> + + + + + + + + + + + +query('SELECT DISTINCT poster_id, poster FROM '.$db->prefix.'posts WHERE poster_ip=\''.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 id, username, email, title, num_posts, status, last_post, registered, admin_note FROM '.$db->prefix.'users WHERE id>1 AND 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 = 'View IP stats - Show posts'; + +?> + + + + + + + + + + + + + + + + + + + + + +'."\n"; + +?> + +
UsernameE-mailTitleRegisteredLast postPostsAdmin noteActions
'.htmlspecialchars($user_data['username']).'' ?>
 Guest     
The supplied IP address could not be found in the database.
 
+'.$last_post_after; + if ($last_post_before != '') + $conditions[] = 'last_post<'.$last_post_before; + if ($registered_after != '') + $conditions[] = 'registered>'.$registered_after; + if ($registered_before != '') + $conditions[] = 'registered<'.$registered_before; + + foreach ($form as $key => $input) + { + if ($input != '') + $conditions[] = $key.' LIKE \''.un_escape(str_replace('*', '%', $input)).'\''; + } + + if ($posts_greater != '') + $conditions[] = 'num_posts>'.$posts_greater; + if ($posts_less != '') + $conditions[] = 'num_posts<'.$posts_less; + + if ($user_group != 'all') + $conditions[] = 'status='.$user_group; + + if (!isset($conditions)) + message('You didn\'t enter any search terms.'); + + + $page_title = htmlspecialchars($options['board_title']).' / Admin / Users'; + require 'header.php'; + + if ($cur_user['status'] > 1) + admin_menu('users'); + else + moderator_menu('users'); + +?> + + + + + + + + + + + +prefix.'users WHERE id>1 AND '.implode(' AND ', $conditions).' ORDER BY '.$order_by.' '.$direction; + + $result = $db->query($sql) or error('Unable to search for users', __FILE__, __LINE__, $db->error()); + $num_users = $db->num_rows($result); + + if ($num_users) + { + // Loop through users and print out some info + for ($i = 0; $i < $num_users; $i++) + { + $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 validated" for non-validated users + if ($user_data['status'] == -1 && $user_title != $lang_common['Banned']) + $user_title = 'Not validated'; + + $actions = 'View IP stats - Show posts'; + +?> + + + + + + + + + + +'."\n"; + +?> +
UsernameE-mailTitleRegisteredLast postPostsAdmin noteActions
'.htmlspecialchars($user_data['username']).'' ?>
No match.
+ +
 
+ 1) + admin_menu('users'); + else + moderator_menu('users'); + +?> +
+ + + + + + + + +
Users
Find users   + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
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
E-mail address
Title
Real name
Website
ICQ
AOL IM
Yahoo! Messenger
Location
Signature
Admin note
Number of posts greater than
Number of posts less than
Last post is after
(yyyy-mm-dd hh:mm:ss)
Last post is before
(yyyy-mm-dd hh:mm:ss)
Registered after
(yyyy-mm-dd hh:mm:ss)
Registered before
(yyyy-mm-dd hh:mm:ss)
Order by +     +
User group + +
+
+
+ +
 
+ +
+ + + + + + + + +
IP search
Find users   + + + + + + +
IP address
The IP address to search for in the post database.
+
+
+ +
 
+query('SELECT poster, poster_id, message, smilies, topic_id FROM '.$db->prefix.'posts WHERE 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); + +// Determine whether this post is the "topic post" or not +$result = $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()); +$topicpost_id = $db->result($result, 0); + +$is_topicpost = ($id == $topicpost_id) ? true : false; + +// Fetch some info from the topic in which the post is located +$result = $db->query('SELECT subject, closed, forum_id FROM '.$db->prefix.'topics WHERE id='.$cur_post['topic_id']) or error('Unable to fetch topic info', __FILE__, __LINE__, $db->error()); +list($subject, $topic_closed, $forum_id) = $db->fetch_row($result); + +$forum_closed = '0'; +$is_admmod = is_admmod($forum_id, $forum_closed, $admmod_only); + +// If the current user isn't an administrator or a moderator of this forum +if (!$is_admmod) +{ + if ($admmod_only == '1' && $cur_user['status'] < 1 || + $topic_closed == '1' || + $forum_closed == '1' || + $permissions['users_del_post'] == '0' && $cur_user['status'] < 1 || + $is_topicpost && $permissions['users_del_topic'] == '0' && $cur_user['status'] < 1 || + $cur_post['poster_id'] != $cur_user['id']) + message($lang_common['No permission']); +} + + +if (isset($_POST['delete'])) +{ + if ($is_admmod) + confirm_referer('delete.php'); + + require 'include/searchidx.php'; + + // If it isn't the topic post + if (!$is_topicpost) + { + $result = $db->query('SELECT id, poster, posted FROM '.$db->prefix.'posts WHERE topic_id='.$cur_post['topic_id'].' ORDER BY posted 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 (start transaction) + $db->query('DELETE FROM '.$db->prefix.'posts WHERE id='.$id, PUN_TRANS_START) or error('Unable to delete post', __FILE__, __LINE__, $db->error()); + + strip_search_index($id); + + // If the message we deleted is the most recent in the topic (at the end of the topic) + if ($last_id == $id) + { + // If there is a $second_last_id there is more than 1 reply to the topic + if ($second_last_id != NULL) + $db->query('UPDATE '.$db->prefix.'topics SET last_post='.$second_posted.', last_post_id='.$second_last_id.', last_poster=\''.addslashes($second_poster).'\', num_replies=num_replies-1 WHERE id='.$cur_post['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-1 WHERE id='.$cur_post['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-1 WHERE id='.$cur_post['topic_id']) or error('Unable to update topic', __FILE__, __LINE__, $db->error()); + + update_forum($forum_id, PUN_TRANS_END); // end transaction + + redirect('viewtopic.php?id='.$cur_post['topic_id'], $lang_delete['Post del redirect']); + } + else // It's the topic post + { + // Delete the topic and any redirect topics (start transaction) + $db->query('DELETE FROM '.$db->prefix.'topics WHERE id='.$cur_post['topic_id'].' OR moved_to='.$cur_post['topic_id'], PUN_TRANS_START) or error('Unable to delete topic', __FILE__, __LINE__, $db->error()); + + // Create a list of the post ID's in this topic and then strip the search index + $result = $db->query('SELECT id FROM '.$db->prefix.'posts WHERE topic_id='.$cur_post['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]; + + strip_search_index($post_ids); + + // Delete posts in topic + $db->query('DELETE FROM '.$db->prefix.'posts WHERE topic_id='.$cur_post['topic_id']) or error('Unable to delete posts', __FILE__, __LINE__, $db->error()); + + update_forum($forum_id, PUN_TRANS_END); // end transaction + + redirect('viewforum.php?id='.$forum_id, $lang_delete['Topic del redirect']); + } +} + + +else +{ + $page_title = htmlspecialchars($options['board_title']).' / '.$lang_delete['Delete post']; + require 'header.php'; + + require 'include/parser.php'; + + $cur_post['message'] = parse_message($cur_post['message'], $cur_post['smilies']); + +?> +
 
+ +
+ + + + + + + + + + + + + + + + +
   
   + + +
+
   +
 

+      

+
+
+ +
 
+ + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/docs/example_config.php b/docs/example_config.php new file mode 100644 index 0000000..1bf7f49 --- /dev/null +++ b/docs/example_config.php @@ -0,0 +1,21 @@ + + + +PunBB 1.0 Installation + + +

PunBB 1.0 Installation

+ +

NOTE: If you are upgrading from 1.0 RC 2, skip to section 3.

+ +

1. Requirements

+ + + +

MySQL: Version 3.23 or later is recommended. PunBB will probably +work with older versions though.

+ +

PostgreSQL: PunBB 1.0 has only been tested on version 7.3.3 of +PostgreSQL. It should work fine with any version greater than 7.0 +though. If the installer complains about not being able to create +an index, open up install.php and search for "PostgreSQL <7.3 +note".

+ +

2. Installation

+ +

Copy/upload all files and directories and run install.php from +the forum root directory. Follow the instructions. If you get an +error when trying to upload avatar images, make sure that PHP has +write access to the directory where you store avatars (default is +img/avatars). Please report any problems you might encounter during +installation in the forums at http://forums.punbb.org/.

+ +

3. Upgrading from 1.0 RC 2

+ +

Follow these instructions to update your current 1.0 RC 2 +installation to 1.0 final. It is recommended that the forum be put +into maintenance mode (Admin/Options) during the update +procedure.

+ +

NOTE: Make a backup before proceeding! Use the tool mysqldump +for MySQL and pg_dump for PostgreSQL. Also backup any CSS and +template files that you have made changes to.

+ +
    +
  1. Update all scripts and files to 1.0. This is easily done by +extracting the 1.0 archive into the same directory as your old +installation (overwriting any existing files).
  2. + +
  3. Copy the script 10_rc2_to_10_update.php from the directory +"extra" to the forum root directory and run it once. A message will +appear when the update process has completed. Once the update +script has finished you should remove the script from the forum +root directory.
  4. + +
  5. Update any custom made css files so that the identifier names +no longer contain the character underscore. I.e. make "pun_head" +into "punhead".
  6. +
+ +

You should now be running PunBB 1.0.

+ +

3. Maximizing performance

+ +

Here are some recommendations for maximizing the performance of +PunBB. The recommendations are not directly related to PunBB +performance. They are very general and results may vary.

+ +
    +
  • Run it in a UNIX-like operating system!
  • + +
  • Use the Apache webserver and compile PHP as a static module for +Apache.
  • + +
  • Use a PHP caching tool (UNIX only). I recommend PHP Accelerator by Nick +Lindridge.
  • + +
  • Make sure that PHP has zlib support so you can enable gzip +output compression in Admin/Options. This greatly reduces the size +of the HTML output at the cost of a little CPU time. An alternative +is to use the Apache module mod_gzip. The two methods yield similar +results.
  • + +
  • Visit the administration interface and disable any forum +features that are not used or you feel are unnecessary.
  • +
+ +

Thank you for using PunBB.
+
+Rickard Andersson
+punbb@telia.com
+http://www.punbb.org/
+

+ + diff --git a/edit.php b/edit.php new file mode 100644 index 0000000..6038552 --- /dev/null +++ b/edit.php @@ -0,0 +1,218 @@ +query('SELECT poster, poster_id, message, smilies, topic_id FROM '.$db->prefix.'posts WHERE 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); + +// Determine whether this post is the "topic post" or not +$result = $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()); +$topicpost_id = $db->result($result, 0); + +$is_topicpost = ($id == $topicpost_id) ? true : false; + +// Fetch some info from the topic in which the post is located +$result = $db->query('SELECT subject, closed, forum_id FROM '.$db->prefix.'topics WHERE id='.$cur_post['topic_id']) or error('Unable to fetch topic info', __FILE__, __LINE__, $db->error()); +list($subject, $topic_closed, $forum_id) = $db->fetch_row($result); + +$forum_closed = '0'; +$is_admmod = is_admmod($forum_id, $forum_closed, $admmod_only); + +// If the current user isn't an administrator or a moderator of this forum +if (!$is_admmod) +{ + if ($admmod_only == '1' && $cur_user['status'] < 1 || + $topic_closed == '1' || + $forum_closed == '1' || + $permissions['users_edit_post'] == '0' && $cur_user['status'] < 1 || + $cur_post['poster_id'] != $cur_user['id']) + message($lang_common['No permission']); +} + + +if (isset($_POST['form_sent'])) +{ + if ($is_admmod) + confirm_referer('edit.php'); + + $smilies = $_POST['smilies']; + + // If it is a topic it must contain a subject + if ($is_topicpost && $is_admmod) + { + $subject = trim(un_escape($_POST['req_subject'])); + + if ($subject == '') + message($lang_edit['No subject']); + else if (strlen($subject) > 70) + message($lang_edit['Too long subject']); + else if ($permissions['subject_all_caps'] == '0' && !preg_match('/[[:lower:]]/', $subject) && $cur_user['status'] < 1) + message($lang_edit['No caps subject']); + } + + // Make sure all newlines are \n and not \r\n or \r + $message = str_replace("\r", "\n", str_replace("\r\n", "\n", trim(un_escape($_POST['req_message'])))); + + if ($message == '') + message($lang_edit['No message']); + else if (strlen($message) > 65535) + message($lang_edit['Too long message']); + else if ($permissions['message_all_caps'] === '0' && !preg_match("/[[:lower:]]/", $message) && $cur_user['status'] < 1) + message($lang_edit['No caps message']); + + + // Validate BBCode syntax + if ($permissions['message_bbcode'] == '1' && strpos($message, '[') !== false && strpos($message, ']') !== false) + { + // Change all BBCodes to lower case (this way a lot of regex searches can be case sensitive) + $a = array('[B]', '[I]', '[U]', '[/B]', '[/I]', '[/U]'); + $b = array('[b]', '[i]', '[u]', '[/b]', '[/i]', '[/u]'); + $message = str_replace($a, $b, $message); + + $a = array("#\[quote\]#i", "#\[/quote\]#i", "#\[code\]#i", "#\[/code\]#i", "#\[colou?r=([a-zA-Z]*|\#?[0-9a-fA-F]{6})\]#i", "#\[/colou?r\]#i", "#\[img\]#i", "#\[/img\]#i", "#\[email\]#i", "#\[email=#i", "#\[/email\]#i", "#\[url\]#i", "#\[url=#i", "#\[/url\]#i"); + $b = array('[quote]', '[/quote]', '[code]', '[/code]', "[color=\\1]", '[/color]', '[img]', '[/img]', '[email]', '[email=', '[/email]', '[url]', '[url=', '[/url]'); + $message = preg_replace($a, $b, $message); + + require 'include/parser.php'; + if ($overflow = check_tag_order($message)) + // The quote depth level was too high, so we strip out the inner most quote(s) + $message = substr($message, 0, $overflow[0]).substr($message, $overflow[1], (strlen($message) - $overflow[0])); + } + + + require 'include/searchidx.php'; + + if ($smilies != '1') $smilies = '0'; + + if (!isset($_POST['silent']) || !$is_admmod) + $edited_sql = ', edited='.time().', edited_by=\''.addslashes($cur_user['username']).'\''; + + if ($is_topicpost && $is_admmod) + { + // Update the topic + $db->query('UPDATE '.$db->prefix.'topics SET subject=\''.addslashes($subject).'\' WHERE id='.$cur_post['topic_id']) or error('Unable to update topic', __FILE__, __LINE__, $db->error()); + + // Update any redirect topics as well + $db->query('UPDATE '.$db->prefix.'topics SET subject=\''.addslashes($subject).'\' WHERE moved_to='.$cur_post['topic_id']) or error('Unable to update redirect 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=\''.addslashes($message).'\', smilies=\''.$smilies.'\''.isset($edited_sql).' WHERE id='.$id) or error('Unable to update post', __FILE__, __LINE__, $db->error()); + + redirect('viewtopic.php?pid='.$id.'#'.$id, $lang_edit['Edit redirect']); +} + + +else +{ + if ($options['smilies'] == '1') + { + if ($cur_post['smilies'] == '1') + $checkboxes[] = ' '.$lang_edit['Show smilies']; + else + $checkboxes[] = ' '.$lang_edit['Show smilies']; + } + + if ($is_admmod) + $checkboxes[] = ' '.$lang_edit['Silent edit']; + + if (isset($checkboxes)) + $checkboxes = implode('
'."\n\t\t\t\t", $checkboxes); + + + $page_title = htmlspecialchars($options['board_title']).' / '.$lang_edit['Edit message']; + $validate_form = true; + $form_name = 'edit'; + $focus_element = 'req_message'; + require 'header.php'; + +?> +
 
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
   
   
+   

+ HTML:   
+ BBCode:   
+ [img] tag:   
+ Smilies:    +
 
   + +
  
     

+
+ +
 
+An error was encountered

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

'."\n".'PunBB reported: '.$message."\n"; + + if ($db_error != false) + print '
Database reported: '.htmlspecialchars($db_error['error']).' (Errno: '.$db_error['errno'].')'."\n"; + + exit; +} + + +// Update posts, topics, lastpost, lastpostid and lastposter for a forum (orphaned topics are not included) +function update_forum($forum_id) +{ + global $db; + + $result = $db->query('SELECT COUNT(id), SUM(num_replies) FROM '.$db->prefix.'topics WHERE moved_to IS NULL AND 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=\''.addslashes($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=0, num_posts=0, 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()); +} + + +// Load DB abstraction layer and try to connect +require 'include/dblayer/commondb.php'; + + +// Check current version +$result = $db->query('SELECT cur_version FROM '.$db->prefix.'options'); +if (!$result || $db->result($result, 0) != $update_from) + error('This script can only update version '.$update_from.'. The database "'.$db_name.'" doesn\'t seem to be running that version. Update process aborted.', __FILE__, __LINE__); + + + +switch ($db_type) +{ + case 'mysql': + $query = 'ALTER TABLE '.$db->prefix."posts MODIFY poster_id INT(10) UNSIGNED NOT NULL DEFAULT '1'"; + break; + + case 'pgsql': + $query = 'ALTER TABLE '.$db->prefix."posts ALTER poster_id SET DEFAULT '1'"; + break; +} + +$db->query($query) or exit('Error on line: '.__LINE__.'
'.$db_type.' reported: '.current($db->error())); + + +// Move the guest account to ID 1 +$result = $db->query('SELECT MAX(id) FROM '.$db->prefix.'users'); +$new_id = $db->result($result, 0) + 1; // Next available ID + +$db->query('UPDATE '.$db->prefix.'users SET id='.$new_id.' WHERE id=1') or exit('Error on line: '.__LINE__.'
'.$db_type.' reported: '.current($db->error())); +$db->query('UPDATE '.$db->prefix.'posts SET poster_id='.$new_id.' WHERE poster_id=1') or exit('Error on line: '.__LINE__.'
'.$db_type.' reported: '.current($db->error())); +$db->query('UPDATE '.$db->prefix.'reports SET reported_by='.$new_id.' WHERE reported_by=1') or exit('Error on line: '.__LINE__.'
'.$db_type.' reported: '.current($db->error())); +$db->query('UPDATE '.$db->prefix."users SET id=1 WHERE username='Guest'") or exit('Error on line: '.__LINE__.'
'.$db_type.' reported: '.current($db->error())); + + +// This feels like a good time to update lastpost/lastposter for all forums +$result = $db->query('SELECT id FROM '.$db->prefix.'forums') or exit('Error on line: '.__LINE__.'
'.$db_type.' reported: '.current($db->error())); + +while ($row = $db->fetch_row($result)) + update_forum($row[0]); + + +// We'll empty the search results table as well +$db->query('TRUNCATE TABLE '.$db->prefix.'search_results') or exit('Error on line: '.__LINE__.'
'.$db_type.' reported: '.current($db->error())); + + +// Update version information in database +$db->query('UPDATE '.$db->prefix.'options SET cur_version=\''.$update_to.'\'') or exit('Error on line: '.__LINE__.'
'.$db_type.' reported: '.current($db->error())); + + +exit('Update successful! Your forum database has now been updated to version '.$update_to.'. You must now remove this script from the forum root directory!'); diff --git a/extra/prune_unvalidated_users.php b/extra/prune_unvalidated_users.php new file mode 100644 index 0000000..a306b65 --- /dev/null +++ b/extra/prune_unvalidated_users.php @@ -0,0 +1,43 @@ +query('DELETE FROM '.$db->prefix.'users WHERE id>1 AND status=-1') or error('Unable to prune unvalidated users', __FILE__, __LINE__, $db->error()); +print 'success

Now remove this file!'; + +exit; diff --git a/extra/turn_off_maintenance_mode.php b/extra/turn_off_maintenance_mode.php new file mode 100644 index 0000000..451c645 --- /dev/null +++ b/extra/turn_off_maintenance_mode.php @@ -0,0 +1,46 @@ +query('UPDATE '.$db->prefix.'options SET maintenance=0') or error('Unable to turn off maintenance mode', __FILE__, __LINE__, $db->error()); +print 'success

Now remove this file!'; + +exit; diff --git a/footer.php b/footer.php new file mode 100644 index 0000000..3c7760a --- /dev/null +++ b/footer.php @@ -0,0 +1,170 @@ + + + + + +
+ + + + + +
+'.$lang_common['Show new posts'].'
'."\n"; + + print "\t\t\t\t\t\t".''.$lang_common['Show unanswered posts'].'
'."\n"; + print "\t\t\t\t\t\t".''.$lang_common['Show your posts'].'
'."\n"; + print "\t\t\t\t\t\t".''.$lang_common['Mark all as read'].'
'."\n"; + } + else + { + if ($permissions['guests_search'] == '1') + print "\t\t\t\t\t\t".''.$lang_common['Show unanswered posts'].'
'."\n"; + else + print "\t\t\t\t\t\t".' '."\n"; + } +} +else if (isset($footer_style) == 'forum' || isset($footer_style) == 'topic') +{ + // Display the "Jump to" drop list + if ($options['quickjump'] == '1') + { + +?> +
+
+ + +
+'.$lang_common['Move topic'].'
'."\n"; + + if ($closed == '1') + print "\t\t\t\t\t\t".''.$lang_common['Open topic'].'
'."\n"; + else + print "\t\t\t\t\t\t".''.$lang_common['Close topic'].'
'."\n"; + + if ($sticky == '1') + print "\t\t\t\t\t\t".''.$lang_common['Unstick topic'].'
'."\n"; + else + print "\t\t\t\t\t\t".''.$lang_common['Stick topic'].'
'."\n"; + + print "\t\t\t\t\t\t".''.$lang_common['Edit subscribers'].''."\n"; + } + else if ($options['quickjump'] == '0') // Only print out the nbsp if we didn't display the quickjump + print "\t\t\t\t\t\t".' '."\n"; +} +else if (isset($footer_style) == 'show_new') + print "\t\t\t\t\t\t".''.$lang_common['Mark all as read'].'
'."\n"; +else + print "\t\t\t\t\t\t".' '."\n"; + +?> +
+ Powered by PunBB
+ Modified and migrated by Ahmed Kawa
+ Version:
+ © Copyright 2002, 2003 Rickard Andersson +Accelerated by PHP Accelerator '.$_PHPA['VERSION'].''."\n"; + + // Calculate script generation time + $time_diff = sprintf('%.3f', get_microtime() - $pun_start); + + print "\t\t\t\t\t\t".'
[ Generated in '.$time_diff.' seconds, '.$db->get_num_queries().' queries executed ]'."\n"; +} + + + +?> +
+
+close(); diff --git a/header.php b/header.php new file mode 100644 index 0000000..90b2232 --- /dev/null +++ b/header.php @@ -0,0 +1,166 @@ +eneral Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, + MA 02111-1307 USA + +************************************************************************/ + + +// Workaround for "current" Apache 2 + PHP module which seems to not +// cope with private cache control setting (from phpBB2) +if (strpos($_SERVER['SERVER_SOFTWARE'], 'Apache/2') !== 0) + header('Cache-Control: no-cache, pre-check=0, post-check=0, max-age=0'); +else + header('Cache-Control: private, pre-check=0, post-check=0, max-age=0'); + +header('Expires: '.gmdate('D, d M Y H:i:s').' GMT'); +header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT'); + + +// Load the main template +$fp = fopen('include/template/main.tpl', 'r'); +$tpl_main = trim(fread($fp, filesize('include/template/main.tpl'))); +fclose($fp); + + +// START SUBST - {pun_content_direction} +$tpl_main = str_replace('{pun_content_direction}', $lang_common['lang_direction'], $tpl_main); +// END SUBST - {pun_content_direction} + + +// START SUBST - {pun_char_encoding} +$tpl_main = str_replace('{pun_char_encoding}', $lang_common['lang_encoding'], $tpl_main); +// END SUBST - {pun_char_encoding} + + +// START SUBST - {pun_head} +ob_start(); + +if (isset($destination)) + print ''."\n"; +else +{ + if ((isset($form_name) && isset($focus_element)) || isset($validate_form)) + { + // Output javascript(s) + // With a quick and dirty hack to not disable submit buttons if user agent is Opera (since Opera + // refused to re-enable the button if we submit and then go back to this page) + +?> + + +<?php print $page_title ?> + +'.htmlspecialchars($cur_user['username']).'.
'.$lang_common['Last visit'].': '.format_time($cookie['last_timeout']); + +if (isset($cur_user['status']) > 0) +{ + $result_header = $db->query('SELECT COUNT(id) FROM '.$db->prefix.'reports WHERE zapped IS NULL') or error('Unable to fetch reports info', __FILE__, __LINE__, $db->error()); + + if ($db->result($result_header, 0)) + $tpl_temp .= '
There are new reports'; + + if ($options['maintenance'] == '1') + $tpl_temp .= '
Maintenance mode is enabled!'; +} + +$tpl_main = str_replace('{pun_status}', $tpl_temp, $tpl_main); +// END SUBST - {pun_status} + + +// START SUBST - {pun_main} +ob_start(); + + +define('PUN_HEADER', 1); diff --git a/help.php b/help.php new file mode 100644 index 0000000..da65894 --- /dev/null +++ b/help.php @@ -0,0 +1,132 @@ +'.$lang_common['Login'].' '.$lang_common['or'].' '.$lang_common['register'].'.'); + + +// Load the help.php language file +require 'lang/'.$language.'/'.$language.'_help.php'; + +// Determine what style to use (for the [img] example) +if ($cur_user['style'] != '' && @file_exists('style/'.$cur_user['style'].'.css')) + $img_url = $options['base_url'].'/img/'.$cur_user['style'].'_new.png'; +else + $img_url = $options['base_url'].'/img/'.$options['default_style'].'_new.png'; + + +$page_title = htmlspecialchars($options['board_title']).' / '.$lang_help['Help']; +require 'header.php'; + +?> +
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
   +
+

+

+
+
   +
+

+     [b][/b]
+     [u][/u]
+     [i][/i]
+     [color=#FF0000][/color]

+
+
   +
+

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

+

+     [img][/img]

+
+
   +
+

+     [quote][/quote]

+

+

+

+     [code][/code]

+

+
code:


+
+
   +
+

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

+
+
   +
+

+     :) =)
+     :( =(
+     :D =D
+     ;)
+     :x
+     :rolleyes:

+
+
+ +
 
+|1&sft^5My$9uXshE&{2N^oOlU_5f*Ob62pMkWr811&5PGl2}X0|yvH z88{Sp7#kQ431Bcbh$%D}urM%jICDENByupY2(*a-6@HL$U@%-zEw6BZf!Uw&r6cb} Q3!qgDp00i_>zopr0NtBG>Hq)$ literal 0 HcmV?d00001 diff --git a/img/Lithium_new.png b/img/Lithium_new.png new file mode 100644 index 0000000000000000000000000000000000000000..e3238f69039a6c419bc34f55d95bf28b4a8b537d GIT binary patch literal 245 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJOS+@4BLl7>^t{)4?=@k%>d&Knsh+Odvz;zyStP z1`Y)t#s-E%0vL=9VhRlgEDTH>&fE?Ri5v_p0&QYIg&$-b7z`Iw%PSmUVD@Kx>BxK0 Q0%#S3r>mdKI;Vst02H4@7ytkO literal 0 HcmV?d00001 diff --git a/img/Mercury_new.png b/img/Mercury_new.png new file mode 100644 index 0000000000000000000000000000000000000000..9373944733e3813d59a13b0aa736612124702fb9 GIT binary patch literal 245 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJOS+@4BLlF!NeOPu42(w(oatbi!N|m+aiE1oVkVHGcHjVm zCIED7mK^!_?>`V!Z0?u< zGOQ%XFBr&WaL`)$1;~&0ba4!+xRsRP#>~KY4U|=rnLR0_% literal 0 HcmV?d00001 diff --git a/img/Sulfur_new.png b/img/Sulfur_new.png new file mode 100644 index 0000000000000000000000000000000000000000..84dcb65e2df33c4d98f351b6b65f4a7c2721b9e2 GIT binary patch literal 245 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJOS+@4BLl7>^t{)4?=@k%>d&Knsh+Odvz;zyStP z1`Y)t#s-E%0vL=9VhRlgEDTH>&fE?Ri5v_p0&QYIg&$-b7z`Iw%PSmUVD@Kx>BxK0 Q0%#S3r>mdKI;Vst01Hb*3IG5A literal 0 HcmV?d00001 diff --git a/img/avatars/index.html b/img/avatars/index.html new file mode 100644 index 0000000..2db9a3c --- /dev/null +++ b/img/avatars/index.html @@ -0,0 +1,8 @@ + + +. + + +. + + \ No newline at end of file diff --git a/img/index.html b/img/index.html new file mode 100644 index 0000000..2db9a3c --- /dev/null +++ b/img/index.html @@ -0,0 +1,8 @@ + + +. + + +. + + \ No newline at end of file diff --git a/img/smilies/big_smile.png b/img/smilies/big_smile.png new file mode 100644 index 0000000000000000000000000000000000000000..d3a7d9fefa6d046318f2c331d4ed58f9777d0f12 GIT binary patch literal 401 zcmeAS@N?(olHy`uVBq!ia0vp^{2|(nD;N|SBwBXdywR}f zPfg68o*o`22F4=_N3>cPWFRah6%7s-1)e9&ECS5}!d&uT^%H*B0A*QB=7)2fV)x<( z%1t=W`1~^mCy;fbmWL_fFl$3hVgp0dj`@v^&CTp@>KYi596rlCG%zx-&*lw3W6`Mr P^ag{ctDnm{r-UW|y+E4m literal 0 HcmV?d00001 diff --git a/img/smilies/index.html b/img/smilies/index.html new file mode 100644 index 0000000..2db9a3c --- /dev/null +++ b/img/smilies/index.html @@ -0,0 +1,8 @@ + + +. + + +. + + \ No newline at end of file diff --git a/img/smilies/mad.png b/img/smilies/mad.png new file mode 100644 index 0000000000000000000000000000000000000000..64853e10591c44ddd678a4dd153c7ec7949d2395 GIT binary patch literal 417 zcmeAS@N?(olHy`uVBq!ia0vp^{2G_>%JC+sv|Nq~?LIFrl+V;H* zXpTrpkY6y6iw+q4{htd0bP0l+XkK773dJ literal 0 HcmV?d00001 diff --git a/img/smilies/roll.png b/img/smilies/roll.png new file mode 100644 index 0000000000000000000000000000000000000000..0599674af61e3ed31c8b8c7d85d9b85a9bdb6d12 GIT binary patch literal 440 zcmeAS@N?(olHy`uVBq!ia0vp^{2 z99paN?T*2jZK}`D=^Wpva^s-J|L>On|2sZ9rTzcE?Y(1~=XR*RzNCBmh{pf_rAsEu z{QUXT!9wBx|Nla!n^J*hN|Xfo1p~R*0K-{fy;ndrmpok@Ln>}139vI73NUPDVCrBz zBmC@fS{idV1B<`}eYG>pPmDGcaxk!hq>hLRGk-dIWJko2BaBQOC!RBArZEW4NqWS< zctk->M@@^(C85caN1;LD$d02fjSNm3Iv805nk9^lC+HqyRI-RX0yM<2rc&v*9kkfCEp)KV}XC2B)+9Vq1PSZUFj@!PC{xWt~$( F695BWsw)5h literal 0 HcmV?d00001 diff --git a/img/smilies/sad.png b/img/smilies/sad.png new file mode 100644 index 0000000000000000000000000000000000000000..c38a392e569a28cd95eb583bc4d9d6111650789d GIT binary patch literal 425 zcmeAS@N?(olHy`uVBq!ia0vp^{24jZtUv3#JnyBbtq459z|Gfvl zS^~`xDGBlm26E8>gTMcCL7@C)PZ!6Kid#tnY>bKm44WC4IvCG9PJWh}$lT4qA~1pf ziJ|f5O$KdJe=d#Wzp$Pz=2cIPX literal 0 HcmV?d00001 diff --git a/img/smilies/smile.png b/img/smilies/smile.png new file mode 100644 index 0000000000000000000000000000000000000000..ea3f05bd48e5015e201929d9237e5162193779a9 GIT binary patch literal 420 zcmeAS@N?(olHy`uVBq!ia0vp^{2fi1d z{C#Bf|Bcz3%X-@v%kNpPaA>X4>8&asuj?P%sQmxG{kffL|NocH?a^|uQ277<|7O)2 zhCp*fN`m}?fn0RJ;P3xj5Ga4n)5S5Q;#QIX8>6BC!)6Ai4#qRW50aCT8M_%+1Sar5 zVcfY!hv$z2V*^7HL$PCx9Gjb;VqyaW)2E+5T3Q+|IXU(0aXQ4nc!c4Sw#t!HhxAmA zoH?t=BH+N|6!NTtcBi;ob8G o4_H1qykqB3U^Ds8$Rfd@Ccv%mzHP+{pwAdQUHx3vIVCg!06jpUM*si- literal 0 HcmV?d00001 diff --git a/img/smilies/wink.png b/img/smilies/wink.png new file mode 100644 index 0000000000000000000000000000000000000000..a9014b0673fb0488d954a0720f40de3e9abc36e6 GIT binary patch literal 416 zcmeAS@N?(olHy`uVBq!ia0vp^{2fi1d z{C{Qo=aJEy%X*6@DxTh^x@(#Ip|wgMuj?P%sP_NA!}*EaktaVtrHjZsm6VKW0$2jdyx6rqGv#%=}{feHF5 zCypOiIdJUI0e%q%4h1%i=~H{#8z*{uNGLQk)NqKem@_dP#Fl8Ns%&iAxPhC~u(*hm zkwu_+LIZ<#z_huIjeRx5U1alivY-#o+1c=d#Wzp$P!a)}pBZ literal 0 HcmV?d00001 diff --git a/include/common.php b/include/common.php new file mode 100644 index 0000000..eb16da2 --- /dev/null +++ b/include/common.php @@ -0,0 +1,815 @@ +query('SELECT * FROM '.$db->prefix.'options, '.$db->prefix.'permissions') or error('Unable to fetch forum options and permissions', __FILE__, __LINE__, $db->error()); +$optperm = $db->fetch_assoc($result); + +// The first 48 elements should be options and the rest permissions +list($options, $permissions) = array_chunk($optperm, 48, true); + + +// Enable output buffering +if (!defined('PUN_DISABLE_BUFFERING')) +{ + // Should we use gzip output compression? + if ($options['gzip'] == '1' && extension_loaded('zlib') && (strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') !== false || strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'deflate') !== false)) + ob_start('ob_gzhandler'); + else + ob_start(); +} + + +// Check/update/set cookie and fetch user info +$cookie = check_cookie($cur_user); + +// Check if we are to display a maintenance message +if ($options['maintenance'] == '1' && $cur_user['status'] < 2 && !defined('PUN_TURN_OFF_MAINT')) + maintenance_message(); + + +// Check if current user is banned +check_bans(); + +// Update online list +update_users_online(); + + +// +// Cookie stuff! +// +function check_cookie(&$cur_user) +{ + global $db, $cookie_path, $cookie_domain, $cookie_secure, $options; + + $now = time(); + $expire = $now + 31536000; // The cookie expires after a year + + if (isset($_COOKIE['punbb_cookie'])) + { + $cookie = array(); + $punbb_cookie = $_COOKIE['punbb_cookie'] ?? ''; + if ($punbb_cookie) { + $cookie_values = unserialize(urldecode($punbb_cookie)); + if (is_array($cookie_values)) { + $cookie['username'] = $cookie_values[0] ?? ''; + $cookie['password'] = $cookie_values[1] ?? ''; + $cookie['last_action'] = $cookie_values[2] ?? ''; + $cookie['last_timeout'] = $cookie_values[3] ?? ''; + } + } + + + if (strcasecmp($cookie['username'], 'Guest')) + { + $result = $db->query('SELECT * FROM '.$db->prefix.'users WHERE username=\''.addslashes($cookie['username']).'\'') or error('Unable to fetch user information', __FILE__, __LINE__, $db->error()); + $cur_user = $db->fetch_assoc($result); + + if (!is_null($cur_user) && isset($cur_user['disp_topics']) && $cur_user['disp_topics'] == '') { + $cur_user['disp_topics'] = $options['disp_topics_default']; + } + + if (!isset($cur_user['disp_posts']) || $cur_user['disp_posts'] == '') + $cur_user['disp_posts'] = $options['disp_posts_default']; + + // Determine what style to use + if (!@file_exists('style/'.$cur_user['style'].'.css')) + $cur_user['style'] = $options['default_style']; + + // If the user couldn't be found or if the password was incorrect + if (!$cur_user || !isset($cookie['password']) || !isset($cur_user['password']) || md5($cookie['password']) !== md5($cur_user['password'])) +{ + setcookie('punbb_cookie', serialize(array('Guest', 'Guest', $now, $now)), $expire, $cookie_path, $cookie_domain, $cookie_secure); + + $cookie['username'] = 'Guest'; + $cookie['password'] = 'Guest'; + $cookie['last_action'] = $now; + $cookie['last_timeout'] = $now; + $cookie['is_guest'] = true; + + return $cookie; +} + + + + if ($cur_user['save_pass'] == '0') + $expire = 0; + + // Define this if you don't want PunBB to update the current users cookie + if (!defined('PUN_DONT_UPDATE_COOKIE')) + { + // Has the user been idle longer than timeout_cookie? + if ($now > ($cookie['last_action'] + $options['timeout_cookie'])) + { + $cookie['last_timeout'] = $cookie['last_action']; + $cookie['last_action'] = $now; + + setcookie('punbb_cookie', serialize(array($cookie['username'], $cookie['password'], $now, $cookie['last_timeout'])), $expire, $cookie_path, $cookie_domain, $cookie_secure); + } + else + { + $cookie['last_action'] = $now; + + setcookie('punbb_cookie', serialize(array($cookie['username'], $cookie['password'], $now, $cookie['last_timeout'])), $expire, $cookie_path, $cookie_domain, $cookie_secure); + } + } + + $cookie['is_guest'] = false; + } + else + $cookie['is_guest'] = true; + } + else + { + $cookie['username'] = 'Guest'; + $cookie['password'] = 'Guest'; + $cookie['last_action'] = $now; + $cookie['last_timeout'] = $now; + $cookie['is_guest'] = true; + } + + return $cookie; +} + + +// +// Try to determine the correct remote IP-address +// +function get_remote_address() +{ + // If HTTP_X_FORWARDED_FOR is set we grab the first address in the list + if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) + { + if (preg_match('/[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}/', $_SERVER['HTTP_X_FORWARDED_FOR'], $addresses)) + return $addresses[0]; + } + + // If no address was found in HTTP_X_FORWARDED_FOR, we try HTTP_CLIENT_IP and if that isn't set we return REMOTE_ADDR + return (isset($_SERVER['HTTP_CLIENT_IP'])) ? $_SERVER['HTTP_CLIENT_IP'] : $_SERVER['REMOTE_ADDR']; +} + + +// +// Add slashes only if magic_quotes_gpc is off +// +function escape($str) +{ + $magic_quotes_active = (bool) ini_get('magic_quotes_gpc'); + if ($magic_quotes_active) { + $str = stripslashes($str); + } + return addslashes($str); +} + + + +// +// Strip slashes only if magic_quotes_gpc is on +// +function un_escape($str) +{ + return (ini_get('magic_quotes_gpc') == 1) ? stripslashes($str) : $str; +} + + +// +// Check whether the connecting user is banned (and delete any expired bans) +// +function check_bans() +{ + global $db, $cookie, $options, $lang_common; + + $ip = get_remote_address(); + + $result = $db->query('SELECT id, username, ip, expire FROM '.$db->prefix.'bans WHERE username IS NOT NULL OR ip IS NOT NULL OR expire IS NOT NULL') or error('Unable to fetch ban list', __FILE__, __LINE__, $db->error()); + + while ($row = $db->fetch_row($result)) + { + if ($row[3] != '' && $row[3] <= time()) + { + $db->query('DELETE FROM '.$db->prefix.'bans WHERE id='.$row[0]) or error('Unable to delete expired ban', __FILE__, __LINE__, $db->error()); + continue; + } + + if (($row[1] != '' && !strcasecmp($cookie['username'], $row[1])) || ($row[2] != '' && !strcmp(substr($ip, 0, strlen($row[2])), $row[2]))) + message($lang_common['Banned message'].' '.$options['admin_email'].'.'); + } +} + + +// +// Update "Users online" +// +function update_users_online() +{ + global $db, $cookie, $cur_user, $options; + + if (!$cookie['is_guest']) + { + $user_id = $cur_user['id']; + $ident = addslashes($cookie['username']); + } + else + { + $user_id = 0; + $ident = get_remote_address(); + } + + $now = time(); + + // Delete entries older than timeout_online seconds and any duplicates (start transaction) + $db->query('DELETE FROM '.$db->prefix.'online WHERE logged<'.($now-$options['timeout_online']).' OR ident=\''.addslashes($cookie['username']).'\' OR ident=\''.get_remote_address().'\'', PUN_TRANS_START) or error('Unable to delete from online list', __FILE__, __LINE__, $db->error()); + + // Add a new entry. username and user_id if logged in; ip and user_id=0 if not (end transaction) + $db->query('INSERT INTO '.$db->prefix.'online (user_id, ident, logged) VALUES(\''.$user_id.'\', \''.$ident.'\', '.$now.')', PUN_TRANS_END) or error('Unable to insert into online list', __FILE__, __LINE__, $db->error()); +} + + +// +// Format a time string according to $time_format and timezones +// +function format_time($timestamp, $date_only = false) +{ + global $cur_user, $options, $lang_common; + + if ($timestamp == '') + return $lang_common['Never']; + + if (!isset($cur_user) || !isset($cur_user['timezone']) || $options['server_timezone'] == $cur_user['timezone']) + $diff = 0; + else if ($options['server_timezone'] < $cur_user['timezone']) + { + if ($options['server_timezone'] >= 0 && $cur_user['timezone'] >= 0) + $diff = $cur_user['timezone'] - $options['server_timezone']; + else if ($options['server_timezone'] < 0 && $cur_user['timezone'] >= 0) + $diff = (-1*$options['server_timezone']) + $cur_user['timezone']; + else if ($options['server_timezone'] < 0 && $cur_user['timezone'] < 0) + $diff = $cur_user['timezone'] - $options['server_timezone']; + } + else + { + if ($options['server_timezone'] >= 0 && $cur_user['timezone'] >= 0) + $diff = $cur_user['timezone'] - $options['server_timezone']; + else if ($options['server_timezone'] >= 0 && $cur_user['timezone'] < 0) + $diff = (-1*$options['server_timezone']) + $cur_user['timezone']; + else if ($options['server_timezone'] < 0 && $cur_user['timezone'] < 0) + $diff = $cur_user['timezone'] - $options['server_timezone']; + } + + + $timestamp += $diff * 3600; + + $now = time(); + + $date = date($options['date_format'], $timestamp); + $today = date($options['date_format'], $now); + $yesterday = date($options['date_format'], $now-86400); + + if ($date == $today) + $date = $lang_common['Today']; + else if ($date == $yesterday) + $date = $lang_common['Yesterday']; + + if (!$date_only) + return $date.' '.date($options['time_format'], $timestamp); + else + return $date; +} + + +// +// Generate the "navigator" that appears at the top of every page +// +function generate_navlinks() +{ + global $cur_user, $options, $permissions, $cookie, $lang_common; + + $links[] = ''.$lang_common['Home'].' | '.$lang_common['User list'].''; + + if ($options['rules'] == '1') + $links[] = ''.$lang_common['Rules'].''; + + if ($cookie['is_guest']) + { + if ($options['search'] == '1' && $permissions['guests_search'] == '1') + $links[] = ''.$lang_common['Search'].''; + + $links[] = ''.$lang_common['Register'].' | '.$lang_common['Login'].''; + + $info = $lang_common['Not logged in']; + } + else + { + if ($cur_user['status'] < 1) + { + if ($options['search'] == '1') + $links[] = ''.$lang_common['Search'].''; + + $links[] = ''.$lang_common['Profile'].''; + $links[] = ''.$lang_common['Logout'].''; + } + else + { + $links[] = ''.$lang_common['Search'].''; + $links[] = ''.$lang_common['Profile'].''; + $links[] = ''.$lang_common['Admin'].''; + $links[] = ''.$lang_common['Logout'].''; + } + } + + return implode(' | ', $links); +} + + +// +// Update posts, topics, last_post, last_post_id and last_poster for a forum (redirect topics are not included) +// If $transaction == PUN_TRANS_END, this function will end the current transaction +// +function update_forum($forum_id, $transaction = 0) +{ + global $db; + + $result = $db->query('SELECT COUNT(id), SUM(num_replies) FROM '.$db->prefix.'topics WHERE moved_to IS NULL AND 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; // $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=\''.addslashes($last_poster).'\' WHERE id='.$forum_id, $transaction) 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=0, num_posts=0, last_post=NULL, last_post_id=NULL, last_poster=NULL WHERE id='.$forum_id, $transaction) or error('Unable to update last_post/last_post_id/last_poster', __FILE__, __LINE__, $db->error()); +} + + +// +// Check whether the current user is an administrator or a moderator in $forum_id (also check if forum is closed and/or admmod_only) +// +function is_admmod($forum_id, &$forum_closed, &$admmod_only) +{ + global $db, $cur_user; + + $result = $db->query('SELECT moderators, admmod_only, closed FROM '.$db->prefix.'forums WHERE id='.$forum_id) or error('Unable to fetch forum info', __FILE__, __LINE__, $db->error()); + + if ($db->num_rows($result)) + { + list($moderators, $admmod_only, $forum_closed) = $db->fetch_row($result); + $mods_array = ($moderators != '') ? unserialize($moderators) : array(); + + return (isset($cur_user['status']) == 2 || (isset($cur_user['status']) == 1 && array_key_exists($cur_user['username'], $mods_array))) ? true : false; + } + else + return false; +} + + +// +// Replace censored words in $text +// +function censor_words($text) +{ + global $db; + static $search_for, $replace_with; + + // If not already built, build an array of censor words and their replacement text + if (empty($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); + + if ($num_words) + { + 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'; + } + } + else + $search_for[] = 1; // Dummy entry + } + + if (!empty($search_for) && $search_for[0] != 1) + $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', 'status' and 'posts' +// +function get_title($user) +{ + global $db, $lang_common; + static $ban_list, $ranklist; + + // If not already built, build an array of banned usernames + if (empty($ban_list)) + { + $ban_list[] = 1; // Dummy entry + + $result = $db->query('SELECT LOWER(username) FROM '.$db->prefix.'bans WHERE username IS NOT NULL') or error('Unable to fetch banned username list', __FILE__, __LINE__, $db->error()); + + while ($row = $db->fetch_row($result)) + $ban_list[] = $row[0]; + } + + // If not already built, build an array of ranks and their respective minimun number of posts + if (empty($ranklist)) + { + $ranklist[] = 1; // Dummy entry + + $result = $db->query('SELECT rank, min_posts FROM '.$db->prefix.'ranks ORDER BY min_posts') or error('Unable to fetch rank list', __FILE__, __LINE__, $db->error()); + + while ($row = $db->fetch_row($result)) + $ranklist[] = $row; + } + + // If the user has a title + if ($user['title'] != '') + $user_title = htmlspecialchars($user['title']); + // If the user is banned + else if (in_array(strtolower($user['username']), $ban_list)) + $user_title = $lang_common['Banned']; + else if ($user['status'] <= 0) + { + // Are there any ranks? (> 1 because there is a dummy entry) + if (count($ranklist) > 1) + { + @reset($ranklist); + next($ranklist); + foreach ($ranklist as $value) + { + if (intval($user['num_posts']) >= isset($value[1])) + $user_title = htmlspecialchars(isset($value[0])); + } + } + + // If the user didn't "reach" any rank + if ($user_title == '') + $user_title = $lang_common['Member']; + } + else if ($user['status'] == 1) + $user_title = $lang_common['Moderator']; + else + $user_title = $lang_common['Administrator']; + + return $user_title; +} + + +// +// Generate a string with numbered links (appears at the bottom of multipage scripts) +// +function paginate($num_pages, $p, $base_url) +{ + global $lang_common; + + if ($num_pages <= 1) + $string = '1'; + else + { + if ($p > 4) + $string = ''.$lang_common['First page'].' -'; + + // Don't ask me how the following works. It just does, OK? :-) + for ($current=$p-3, $stop=$p+4; $current < $stop; $current++) + { + if ($current < 1 || $current > $num_pages) + continue; + else if ($current != $p) + $string .= ' '.$current.''; + else + $string .= ' '.$current.''; + } + + if ($p < ($num_pages-3)) + $string .= ' - '.$lang_common['Last page'].''; + } + + return $string; +} + + +// +// Make sure that HTTP_REFERER matches $options['base_url']/$script +// +function confirm_referer($script) +{ + global $lang_common, $options; + + if (!preg_match('#^'.preg_quote($options['base_url'].'/'.$script, '#').'#i', $_SERVER['HTTP_REFERER'])) + message($lang_common['Bad referer']); +} + + +// +// Generate a random password of length $len +// +function random_pass($len) +{ + $chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; + + while (strlen($password) < $len) + $password .= substr($chars, (mt_rand() % strlen($chars)), 1); + + return $password; +} + + +// +// Display a message. +// +function message($message, $no_back_link = false) +{ + global $db, $lang_common, $options, $pun_start; + + if (!defined('PUN_HEADER')) + { + global $cur_user, $cookie; + + $page_title = htmlspecialchars($options['board_title']).' / '.$lang_common['Info']; + require 'header.php'; + } + +?> +
 
+ + + + + + + + +
+

+ . +
+ +
 
+', $options['maintenance_message']); + $style = (!empty($cur_user)) ? $cur_user['style'] : $options['default_style']; + + + // Load the maintenance template + $fp = fopen('include/template/maintenance.tpl', 'r'); + $tpl_maint = trim(fread($fp, filesize('include/template/maintenance.tpl'))); + fclose($fp); + + + // START SUBST - {pun_content_direction} + $tpl_maint = str_replace('{pun_content_direction}', $lang_common['lang_direction'], $tpl_maint); + // END SUBST - {pun_content_direction} + + + // START SUBST - {pun_char_encoding} + $tpl_maint = str_replace('{pun_char_encoding}', $lang_common['lang_encoding'], $tpl_maint); + // END SUBST - {pun_char_encoding} + + + // START SUBST - {pun_head} + ob_start(); + +?> +<?php print htmlspecialchars($options['board_title']).' / '.$lang_common['Maintenance'] ?> + + + +<?php print htmlspecialchars($options['board_title']).' / '.$lang_common['Redirecting'] ?> + +
'.''.$lang_common['Click redirect'].''; + $tpl_redir = str_replace('{pun_redir_text}', $tpl_temp, $tpl_redir); + // END SUBST - {pun_redir_text} + + + exit($tpl_redir); +} + + +// +// Display a simple error message +// +function error($message, $file, $line, $db_error = false) +{ + global $options, $db_type; + + // Empty output buffer and stop buffering + ob_end_clean(); + + // "Restart" output buffering if we are using ob_gzhandler (since the gzip header is already sent) + if ($options['gzip'] == '1' && extension_loaded('zlib') && (strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') !== false || strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'deflate') !== false)) + ob_start('ob_gzhandler'); + +?> + + + + + +<?php print htmlspecialchars($options['board_title']) ?> / Error + + + + + + + + + + +
An error was encountered
+File: '.$file.'
'."\n\t\t\t".'Line: '.$line.'

'."\n\t\t\t".'PunBB reported: '.$message."\n"; + + if ($db_error) + print "\t\t\t".'
Database reported: '.htmlspecialchars($db_error['error']).' (Errno: '.$db_error['errno'].')'."\n"; + } + else + print "\t\t\t".'Error: '.$message.'.'."\n"; + +?> +
+ + + +close(); + + exit; +} + + +// DEBUG FUNCTIONS BELOW + +// +// Return current timestamp (with microseconds) as a float +// +function get_microtime() +{ + list($usec, $sec) = explode(' ', microtime()); + return ((float)$usec + (float)$sec); +} + + +// +// Dump contents of variable(s) +// +function dump($var1, $var2 = null) +{ + print '
';
+	print_r($var1);
+
+	if ($var2 != null)
+	{
+		print "\n\n";
+		print_r($var2);
+	}
+
+	print '
'; + exit; +} diff --git a/include/commonadmin.php b/include/commonadmin.php new file mode 100644 index 0000000..60b23b5 --- /dev/null +++ b/include/commonadmin.php @@ -0,0 +1,119 @@ + + + + + + + + + + + + + + + +
CategoriesForumsUsersOptionsPermissionsCensoringRanksBansPruneMaintenanceReports
+ + + + + + + + + +
UsersCensoringBansReports
+ +query('SELECT id FROM '.$db->prefix.'topics WHERE forum_id='.$forum_id.$extra) or error('Unable to fetch topics', __FILE__, __LINE__, $db->error()); + + 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.')') or error('Unable to fetch posts', __FILE__, __LINE__, $db->error()); + + while ($row = $db->fetch_row($result)) + $post_ids .= (($post_ids != '') ? ',' : '').$row[0]; + + if ($post_ids != '') + { + // Delete topics (start transaction) + // End transaction must be done after prune() (i.e. in updateForum() or when deleting a forum) + $db->query('DELETE FROM '.$db->prefix.'topics WHERE id IN('.$topic_ids.')', PUN_TRANS_START) or error('Unable to prune topics', __FILE__, __LINE__, $db->error()); + $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 'include/searchidx.php'; + strip_search_index($post_ids); + } + } +} diff --git a/include/dblayer/commondb.php b/include/dblayer/commondb.php new file mode 100644 index 0000000..16ac5d0 --- /dev/null +++ b/include/dblayer/commondb.php @@ -0,0 +1,48 @@ + + +. + + +. + + \ No newline at end of file diff --git a/include/dblayer/mysql.php b/include/dblayer/mysql.php new file mode 100644 index 0000000..471bc1d --- /dev/null +++ b/include/dblayer/mysql.php @@ -0,0 +1,201 @@ +prefix = $db_prefix; + + // Was a custom port supplied with $db_host? + if (strpos($db_host, ':') !== false) { + list($db_host, $db_port) = explode(':', $db_host); + } + + if (isset($db_port)) { + $this->link_id = mysqli_connect($db_host, $db_username, $db_password, $db_name, null, $db_port); + } else { + $this->link_id = mysqli_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__); + } + } + function start_transaction() + { + return; + } + + function end_transaction() + { + return; + } + + function query($sql, $unbuffered = false) + { + if (defined('PUN_SHOW_QUERIES')) + $q_start = microtime(true); + + if (is_array($sql)) { + $sql = implode(' ', $sql); + } + try { + $this->query_result = mysqli_query($this->link_id, $sql, $unbuffered ? MYSQLI_USE_RESULT : MYSQLI_STORE_RESULT); + } catch (mysqli_sql_exception $exception) { + // handle the exception, such as logging it or displaying an error message + echo 'Error: ' . $exception->getMessage(); + } + +if (!$this->query_result) { + die('Unable to execute query: ' . mysqli_error($this->link_id)); // Updated +} + + if ($this->query_result) + { + if (defined('PUN_SHOW_QUERIES')) + $this->saved_queries[] = array($sql, sprintf('%.5f', microtime(true) - $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) + { + if ($query_id) + { + if ($row) + mysqli_data_seek($query_id, $row); + $cur_row = mysqli_fetch_row($query_id); + return $cur_row[0] ?? false; + } + 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) + { + if ($str === null) { + return ''; + } + + return is_array($str) ? '' : mysqli_real_escape_string($this->link_id, $str); + } + + + + function error2() + { + $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 (is_a($this->query_result, 'mysqli_result')) + mysqli_free_result($this->query_result); + + return mysqli_close($this->link_id); + } + else + return false; + } + +} diff --git a/include/dblayer/pgsql.php b/include/dblayer/pgsql.php new file mode 100644 index 0000000..845c040 --- /dev/null +++ b/include/dblayer/pgsql.php @@ -0,0 +1,306 @@ +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 + { + if ($db_host != 'localhost') + $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 and select database', __LINE__, __FILE__); + else + return $this->link_id; + } + + + function query($sql, $transaction = 0) + { + unset($this->query_result); + + if ($sql != '') + { + $this->num_queries++; + + $sql = preg_replace("/LIMIT ([0-9]+),([ 0-9]+)/", "LIMIT \\2 OFFSET \\1", $sql); + + if ($transaction == PUN_TRANS_START && !$this->in_transaction) + { + $this->in_transaction = true; + + if (!@pg_query($this->link_id, 'BEGIN')) + return false; + } + + $this->query_result = @pg_query($this->link_id, $sql); + if ($this->query_result) + { + if ($transaction == PUN_TRANS_END) + { + $this->in_transaction = false; + + if (!@pg_query($this->link_id, 'COMMIT')) + { + @pg_query($this->link_id, 'ROLLBACK'); + return false; + } + } + + $this->last_query_text[$this->query_result] = $sql; + $this->row_num[$this->query_result] = 0; + + unset($this->row[$this->query_result]); + + return $this->query_result; + } + else + { + if ($this->in_transaction) + @pg_query($this->link_id, 'ROLLBACK'); + + $this->in_transaction = false; + + return false; + } + } + else + { + if ($transaction == PUN_TRANS_END && $this->in_transaction) + { + $this->in_transaction = false; + + if (!@pg_query($this->link_id, 'COMMIT')) + { + @pg_query($this->link_id, 'ROLLBACK'); + return false; + } + } + + return true; + } + } + + + function result($query_id = 0, $row = 0) + { + if (!$query_id) + $query_id = $this->query_result; + + if ($query_id) + return @pg_fetch_result($query_id, $row, 0); + else + return false; + } + + + function fetch_array($query_id = 0) + { + if (!$query_id) + $query_id = $this->query_result; + + if ($query_id) + { + $this->row = @pg_fetch_array($query_id, $this->row_num[$query_id]); + + if ($this->row) + { + $this->row_num[$query_id]++; + return $this->row; + } + } + else + return false; + } + + + function fetch_assoc($query_id = 0) + { + if (!$query_id) + $query_id = $this->query_result; + + if ($query_id) + { + $this->row = @pg_fetch_array($query_id, $this->row_num[$query_id], PGSQL_ASSOC); + + if ($this->row) + { + $this->row_num[$query_id]++; + return $this->row; + } + } + else + return false; + } + + + function fetch_row($query_id = 0) + { + if (!$query_id) + $query_id = $this->query_result; + + if ($query_id) + { + $this->row = @pg_fetch_row($query_id, $this->row_num[$query_id]); + + if ($this->row) + { + $this->row_num[$query_id]++; + return $this->row; + } + } + else + return false; + } + + + function num_rows($query_id = 0) + { + if (!$query_id) + { + $query_id = $this->query_result; + } + + return ($query_id) ? @pg_num_rows($query_id) : false; + } + + + function affected_rows($query_id = 0) + { + if (!$query_id) + $query_id = $this->query_result; + + return ($query_id) ? @pg_affected_rows($query_id) : false; + } + + + function insert_id() + { + $query_id = $this->query_result; + + if ($query_id && $this->last_query_text[$query_id] != '') + { + if (preg_match('/^INSERT[\t\n ]+INTO[\t\n ]+([a-z0-9\_\-]+)/is', $this->last_query_text[$query_id], $tablename)) + { + $sql = 'SELECT currval(\''.$tablename[1].'_id_seq\') AS lastval'; + $temp_q_id = @pg_query($this->link_id, $sql); + + if (!$temp_q_id) + return false; + + $temp_result = @pg_fetch_array($temp_q_id, 0, PGSQL_ASSOC); + + return ($temp_result) ? $temp_result['lastval'] : false; + } + } + + return false; + } + + + function get_num_queries() + { + return $this->num_queries; + } + + + function free_result($query_id = false) + { + if (!$query_id) + $query_id = $this->query_result; + + return ($query_id) ? @pg_freeresult($query_id) : false; + } + + + function error($query_id = 0) + { + if (!$query_id) + $query_id = $this->query_result; + + $result['error'] = trim(@pg_last_error($this->link_id)); + $result['errno'] = -1; + + return $result; + } + + + function close() + { + if ($this->link_id) + { + if ($this->in_transaction) + @pg_query($this->link_id, 'COMMIT'); + + if ($this->query_result) + @pg_freeresult($this->query_result); + + return @pg_close($this->link_id); + } + else + return false; + } +} diff --git a/include/email.php b/include/email.php new file mode 100644 index 0000000..32b9e60 --- /dev/null +++ b/include/email.php @@ -0,0 +1,157 @@ +query('SELECT email FROM '.$db->prefix.'bans WHERE email IS NOT NULL') or error('Unable to fetch e-mail from ban list', __FILE__, __LINE__, $db->error()); + $num_bans = $db->num_rows($result); + + for ($i = 0; $i < $num_bans; $i++) + { + $cur_ban = $db->result($result, $i); + + if (!strcmp($email, $cur_ban) || strpos($cur_ban, '@') === false && stristr($email, "@$cur_ban")) + return true; + } + + return false; +} + + +// +// Wrapper for PHP's mail() +// +/*ini_set('SMTP', 'localhost'); +ini_set('smtp_port', '80'); +*/ +function pun_mail($to, $subject, $message, $headers = '') +{ + global $options; + + if ($options['smtp_host'] != '') + smtp_mail($to, $subject, $message, $headers); + else + 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, $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) == $response)) + error('Unable to send e-mail. Please contact the forum administrator with the following error message: "'.$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 $options; + + $recipients = explode(',', $to); + + if (!($socket = fsockopen($options['smtp_host'], 25, $errno, $errstr, 15))) + error('Could not connect to smtp host "'.$options['smtp_host'].'" ('.$errno.') ('.$errstr.')', __FILE__, __LINE__); + + server_parse($socket, '220'); + + if ($options['smtp_user'] != '' && $options['smtp_pass'] != '') + { + fwrite($socket, 'EHLO ' . $options['smtp_host']."\r\n"); + server_parse($socket, '250'); + + fwrite($socket, 'AUTH LOGIN'."\r\n"); + server_parse($socket, '334'); + + fwrite($socket, base64_encode($options['smtp_user'])."\r\n"); + server_parse($socket, '334'); + + fwrite($socket, base64_encode($options['smtp_pass'])."\r\n"); + server_parse($socket, '235'); + } + else + { + fwrite($socket, 'HELO '.$options['smtp_host']."\r\n"); + server_parse($socket, '250'); + } + + fwrite($socket, 'MAIL FROM: <'.$options['webmaster_email'].'>'."\r\n"); + server_parse($socket, '250'); + + $to_header = 'To: '; + + @reset($recipients); + while (list(, $email) = @each($recipients)) + { + fwrite($socket, 'RCPT TO: <'.$email.'>'."\r\n"); + server_parse($socket, '250'); + + $to_header .= '<'.$email.'>, '; + } + + fwrite($socket, 'DATA'."\r\n"); + server_parse($socket, '354'); + + fwrite($socket, 'Subject: '.$subject."\r\n".$to_header."\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/index.html b/include/index.html new file mode 100644 index 0000000..2db9a3c --- /dev/null +++ b/include/index.html @@ -0,0 +1,8 @@ + + +. + + +. + + \ No newline at end of file diff --git a/include/parser.php b/include/parser.php new file mode 100644 index 0000000..0485c5b --- /dev/null +++ b/include/parser.php @@ -0,0 +1,385 @@ + 0 something is wrong with the quote syntax + if ($q_depth > 0) + message($lang_common['BBCode error'].' '.$lang_common['BBCode error 4']); + else if ($q_depth < 0) + message($lang_common['BBCode error'].' '.$lang_common['BBCode error 5']); + + // If the quote depth level was higher than $max_depth we return the index for the + // beginning and end of the part we should strip out + if (isset($overflow_begin)) + return array($overflow_begin, $overflow_end); + else + return null; +} + + +// +// Truncate URL if longer than 55 characters (add http:// or ftp:// if missing) +// +function truncate_url($url, $link = '') +{ + global $cur_user; + + $full_url = $url; + if (strpos($url, 'www.') === 0) + $full_url = 'http://'.$full_url; + else if (strpos($url, 'ftp.') === 0) + $full_url = 'ftp://'.$full_url; + + // Ok, not very pretty :-) + $link = ($link == '' || $link == $url) ? ((strlen($url) > 55) ? substr($url, 0 , 39).' ... '.substr($url, -10) : $url) : stripslashes($link); + + if ($cur_user['link_to_new_win'] == '0') + return ''.$link.''; + else + return ''.$link.''; +} + + +// +// Convert BBCodes to their HTML equivalent +// +function do_bbcode($message) +{ + global $cur_user; + + if (strpos($message, '[') !== false && strpos($message, ']') !== false) + { + $pattern = array("#\[b\](.*?)\[/b\]#s", + "#\[i\](.*?)\[/i\]#s", + "#\[u\](.*?)\[/u\]#s", + "#\[url\](.*?)\[/url\]#ie", + "#\[url=(.*?)\](.*?)\[/url\]#ie", + "#\[email\](.*?)\[/email\]#i", + "#\[email=(.*?)\](.*?)\[/email\]#i", + "#\[color=([a-zA-Z]*|\#?[0-9a-fA-F]{6})](.*?)\[/color\]#s"); + + $replace = array('$1', + '$1', + '$1', + 'truncate_url("$1")', + 'truncate_url("$1", "$2")', + '$1', + '$2', + '$2'); + + // Run this big regex replacement + /*$message = preg_replace($pattern, $replace, $message);*/ + + if (strpos($message, 'quote]') !== false) + { + $message = str_replace('[quote]', '
', $message); + $message = str_replace('[/quote]', '

', $message); + } + } + + return $message; +} + + +// +// Make hyperlinks clickable +// +function do_clickable($message) +{ + global $cur_user; + + $message = ' '.$message; + + + $message = preg_replace_callback( + '#([\t\n ])([a-z0-9]+?){1}://([\w\-]+\.([\w\-]+\.)*[\w]+(:[0-9]+)?(/[^ \"\n\r\t<]*)?)#i', + function($matches) { + return $matches[1] . truncate_url($matches[2] . '://' . $matches[3]); + }, + $message + ); + + $message = preg_replace_callback( + '#([\t\n ])(www|ftp)\.(([\w\-]+\.)*[\w]+(:[0-9]+)?(/[^ \"\n\r\t<]*)?)#i', + function($matches) { + return $matches[1] . truncate_url($matches[2] . '.' . $matches[3], $matches[2] . '.' . $matches[3]); + }, + $message + ); + return substr($message, 1); +} + + +// +// Convert a series of smilies to images +// +function do_smilies($message) +{ + // Here you can add additional smilies if you like (please note that you must escape singlequote and backslash) + $text = array(':)', '=)', ':(', '=(', ':D', '=D', ';)', ':x', ':rolleyes:'); + $img = array('smile.png', 'smile.png', 'sad.png', 'sad.png', 'big_smile.png', 'big_smile.png', 'wink.png', 'mad.png', 'roll.png'); + + // Uncomment the next row if you add smilies that contain any of the characters &"'<> +// $text = array_map('htmlspecialchars', $text); + + $message = ' '.$message.' '; + + $num_smilies = count($text); + for ($i = 0; $i < $num_smilies; $i++) + $message = preg_replace("#(?<=.\W|\W.|^\W)".preg_quote($text[$i], '#')."(?=.\W|\W.|\W$)#m", '$1'.$text[$i].'$2', $message); + + return substr($message, 1, -1); +} + + +// +// Parse message text +// +function parse_message($message, $smilies) +{ + global $cur_user, $permissions, $options; + + // Deal with some possible "exploits" + $message = preg_replace("#javascript:#i", '_javascript_:', $message); + $message = preg_replace("#about:#i", '_about_:', $message); + + if ($options['censoring'] == '1') + $message = censor_words($message); + + if ($permissions['message_html'] == '0') + $message = htmlspecialchars($message); + + // If the message contains a code tag we have to split it up (text within [code][/code] shouldn't be touched) + if (strpos($message, '[code]') !== false && strpos($message, '[/code]') !== false) + { + list($inside, $outside) = split_text($message, '[code]', '[/code]'); + $outside = array_map('trim', $outside); + $message = implode('<">', $outside); + } + + if ($options['make_links'] == '1') + $message = do_clickable($message); + + if ($smilies == '1' && $options['smilies'] == '1' && isset($cur_user['show_img']) != '0') + $message = do_smilies($message); + + if ($permissions['message_bbcode'] == '1') + { + $message = do_bbcode($message); + + if ($permissions['message_img_tag'] == '1') + { + if (isset($cur_user['show_img']) != '0') + $message = preg_replace('#\[img\](.*?)\[/img\]#s', '', $message); + else + { + if (isset($cur_user['link_to_new_win']) == '0') + $message = preg_replace('#\[img\](.*?)\[/img\]#s', '<image>', $message); + else + $message = preg_replace('#\[img\](.*?)\[/img\]#s', '<image>', $message); + } + } + } + + // Deal with newlines, tabs and multiple spaces + $pattern = array("\n", "\t", ' ', ' '); + $replace = array('
', '    ', '  ', '  '); + $message = str_replace($pattern, $replace, $message); + + // If we split up the message before we have to concatenate it together again (code tags) + if (isset($inside)) + { + $outside = explode('<">', $message); + $message = ''; + + $num_tokens = count($outside); + + for ($i = 0; $i < $num_tokens; $i++) + { + $message .= $outside[$i]; + if ($inside[$i]) + $message .= '

code:

'.trim($inside[$i]).'

'; + } + } + + return $message; +} + + +// +// Parse signature text +// +function parse_signature($message) +{ + global $cur_user, $permissions, $options; + + // Deal with some possible "exploits" + $message = preg_replace('/javascript:/i', '_javascript_:', $message); + $message = preg_replace('/about:/i', '_about_:', $message); + + if ($options['censoring'] == '1') + $message = censor_words($message); + + if ($permissions['sig_html'] == '0') + $message = htmlspecialchars($message); + + if ($options['make_links'] == '1') + $message = do_clickable($message); + + if ($options['smilies_sig'] == '1' && $cur_user['show_img'] != '0') + $message = do_smilies($message); + + if ($permissions['sig_bbcode'] == '1') + { + $message = do_bbcode($message); + + if ($permissions['sig_img_tag'] == '1') + { + if ($cur_user['show_img'] != '0') + $message = preg_replace('#\[img\](.*?)\[/img\]#s', '', $message); + else + { + if ($cur_user['link_to_new_win'] == '0') + $message = preg_replace('#\[img\](.*?)\[/img\]#s', '<image>', $message); + else + $message = preg_replace('#\[img\](.*?)\[/img\]#s', '<image>', $message); + } + } + } + + // Deal with newlines, tabs and multiple spaces + $pattern = array("\n", "\t", ' ', ' '); + $replace = array('
', '    ', '  ', '  '); + $message = str_replace($pattern, $replace, $message); + + return $message; +} diff --git a/include/searchidx.php b/include/searchidx.php new file mode 100644 index 0000000..8c46739 --- /dev/null +++ b/include/searchidx.php @@ -0,0 +1,225 @@ +', '`', '\'', '"', '|', ',', '@', '_', '?', '%', '-', '~', '+', '.', '[', ']', '{', '}', ':', '\\', '/', '=', '#', ';', '!', '*'); + $noise_replace = array(' ', ' ', ' ', ' ', ' ', ' ', ' ', '', '', ' ', ' ', ' ', ' ', '', ' ', ' ', '', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '' , ' ', ' ', ' ', ' ', ' ', ' '); + + $stopwords = @file('lang/'.$language.'/'.$language.'_stopwords.txt'); + } + + // Clean up + $patterns[] = "#[\n\r]+#"; + $patterns[] = '#&[\#a-z0-9]+?;#i'; + $patterns[] = '#\b[\w]+:\/\/[a-z0-9\.\-]+(\/[a-z0-9\?\.%_\-\+=&\/]+)?#'; + $patterns[] = '#\[img:[a-z0-9]{10,}\].*?\[\/img:[a-z0-9]{10,}\]#'; + $patterns[] = '#\[\/?url(=.*?)?\]#'; + $patterns[] = '#\[\/?[a-z\*=\+\-]+(\:?[0-9a-z]+)?:[a-z0-9]{10,}(\:[a-z0-9]+)?=?.*?\]#'; + $text = preg_replace($patterns, ' ', ' '.strtolower($text).' '); + + // Filter out non-alphabetical chars + $text = str_replace($noise_match, $noise_replace, $text); + + // Strip out too long and too short words + $text = preg_replace('#\b([\w]{1,2}|[\w]{21,})\b#is', ' ', $text); + + if (!empty($stopwords)) + { + @reset($stopwords); + foreach ($stopwords as $word) + $text = preg_replace('#\b'.preg_quote(trim($word)).'\b#', ' ', $text); + } + + preg_match_all('#\b([\w]+)\b#', $text, $components); + return array_unique($components[1]); +} + + +// +// 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; + + // Split old and new post/subject to obtain array of 'words' + $words_message = split_words($message); + $words_subject = ($subject) ? split_words($subject) : 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) 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(',', preg_replace('#^(.*)$#', '\'\1\'', $unique_words)).')') 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': + $result = $db->query('INSERT INTO '.$db->prefix.'search_words (word) VALUES'.implode(',', preg_replace('#^(.*)$#', '(\'\1\')', $new_words))) or error('Unable to insert search index words', __FILE__, __LINE__, $db->error()); + break; + + default: + foreach ($new_words as $word) + $result = $db->query('INSERT INTO '.$db->prefix.'search_words (word) VALUES(\''.$word.'\')') or error('Unable to insert search index words', __FILE__, __LINE__, $db->error()); + 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)) + { + 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)) + $result = $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(',', preg_replace('#^(.*)$#', '\'\1\'', $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': + { + $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 = 0; + 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]; + + if ($word_ids != '') + $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/index.html b/include/template/index.html new file mode 100644 index 0000000..2db9a3c --- /dev/null +++ b/include/template/index.html @@ -0,0 +1,8 @@ + + +. + + +. + + \ No newline at end of file diff --git a/include/template/main.tpl b/include/template/main.tpl new file mode 100644 index 0000000..fe477ba --- /dev/null +++ b/include/template/main.tpl @@ -0,0 +1,30 @@ + + + + + +{pun_head} + + + + + + + + + + +
+ {pun_title}
+ {pun_desc} +
+ {pun_navlinks}

+ {pun_status} +
+ +{pun_main} + +{pun_footer} + + + \ No newline at end of file diff --git a/include/template/maintenance.tpl b/include/template/maintenance.tpl new file mode 100644 index 0000000..45abc3d --- /dev/null +++ b/include/template/maintenance.tpl @@ -0,0 +1,20 @@ + + + + + +{pun_head} + + + + + + + + + + +
{pun_maint_heading}
{pun_maint_message}
+ + + \ No newline at end of file diff --git a/include/template/redirect.tpl b/include/template/redirect.tpl new file mode 100644 index 0000000..c069fd3 --- /dev/null +++ b/include/template/redirect.tpl @@ -0,0 +1,22 @@ + + + + + +{pun_head} + + + + + + + + + + +
{pun_redir_heading}
+ {pun_redir_text} +
+ + + \ No newline at end of file diff --git a/index.php b/index.php new file mode 100644 index 0000000..95db0e6 --- /dev/null +++ b/index.php @@ -0,0 +1,235 @@ +'.$lang_common['Login'].' '.$lang_common['or'].' '.$lang_common['register'].'.'); + + +// Load the index.php language file +require 'lang/'.$language.'/'.$language.'_index.php'; + +$page_title = htmlspecialchars($options['board_title']); +require 'header.php'; + +?> +
 
+ + + + + + + + + + +query('SELECT c.id AS cid, c.cat_name, f.id AS fid, f.forum_name, f.forum_desc, f.moderators, f.num_topics, f.num_posts, f.last_post, f.last_post_id, f.last_poster, f.closed FROM '.$db->prefix.'categories AS c INNER JOIN '.$db->prefix.'forums AS f ON c.id=f.cat_id'.$extra.' ORDER BY c.position, cid, f.position') or error('Unable to fetch category/forum list', __FILE__, __LINE__, $db->error()); + +while ($cur_forum = $db->fetch_assoc($result)) +{ + if ($cur_forum['cid'] != $cur_category) // A new category since last iteration? + { + // ... + $cur_category = $cur_forum['cid']; + + // ... + + +?> + + + +'.htmlspecialchars($cur_forum['forum_name']).''; + else + $forum_field = ''.htmlspecialchars($cur_forum['forum_name']).''; + + if ($cur_forum['forum_desc'] != '') + $forum_field .= '
'."\n\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'].' '.htmlspecialchars($cur_forum['last_poster']); + else + $last_post = ' '; + + if (!$cookie['is_guest'] && $cur_forum['last_post'] > $cookie['last_timeout']) + { + if ($cur_user['show_img'] != '0') + $icon = ''; + else + $icon = ''; + } + else + $icon = ' '; + + if ($cur_forum['moderators'] != '') + { + $mods_array = unserialize($cur_forum['moderators']); + $moderators = array(); + + while (list($mod_username, $mod_id) = @each($mods_array)) + { + $mod_username = htmlspecialchars($mod_username); + $moderators[] = ''.$mod_username.''; + } + + $moderators = implode(', ', $moderators); + } + else + $moderators = ' '; + +?> + + + + + + + + +\n\n"; + + +// Show what the current user can and cannot do +if (isset($cur_user) && isset($cur_user['status']) && $cur_user['status'] > 0) { + $perms = ($cur_user['status'] > 0) + ? "{$lang_index['You']} {$lang_index['can']} {$lang_index['post replies']}
+ {$lang_index['You']} {$lang_index['can']} {$lang_index['post topics']}
+ {$lang_index['You']} {$lang_index['can']} {$lang_index['edit posts']}
+ {$lang_index['You']} {$lang_index['can']} {$lang_index['delete posts']}
+ {$lang_index['You']} {$lang_index['can']} {$lang_index['delete topics']}\n" + : ''; +} else if (!$cookie['is_guest']) { + $perms = $lang_index['You'].' '. (($permissions['users_post'] == '1') ? $lang_index['can'] : $lang_index['cannot']) .' '.$lang_index['post replies'].'
'; + $perms .= "\n\t\t\t\t\t\t".$lang_index['You'].' '. (($permissions['users_post_topic'] == '1') ? $lang_index['can'] : $lang_index['cannot']) .' '.$lang_index['post topics'].'
'; + $perms .= "\n\t\t\t\t\t\t".$lang_index['You'].' '. (($permissions['users_edit_post'] == '1') ? $lang_index['can'] : $lang_index['cannot']) .' '.$lang_index['edit posts'].'
'; + $perms .= "\n\t\t\t\t\t\t".$lang_index['You'].' '. (($permissions['users_del_post'] == '1') ? $lang_index['can'] : $lang_index['cannot']) .' '.$lang_index['delete posts'].'
'; + $perms .= "\n\t\t\t\t\t\t".$lang_index['You'].' '. (($permissions['users_del_topic'] == '1') ? $lang_index['can'] : $lang_index['cannot']) .' '.$lang_index['delete topics'].'
'."\n"; +} else { + $perms = $lang_index['You'].' '. (($permissions['guests_post'] == '1') ? $lang_index['can'] : $lang_index['cannot']) .' '.$lang_index['post replies'].'
'; + $perms .= "\n\t\t\t\t\t\t".$lang_index['You'].' '. (($permissions['guests_post_topic'] == '1') ? $lang_index['can'] : $lang_index['cannot']) .' '.$lang_index['post topics'].'
'; + $perms .= "\n\t\t\t\t\t\t".$lang_index['You'].' '.$lang_index['cannot'].' '.$lang_index['edit posts'].'
'.$lang_index['You'].' '.$lang_index['cannot'].' '.$lang_index['delete posts'].'
'.$lang_index['You'].' '.$lang_index['cannot'].' '.$lang_index['delete topics']."\n"; +} + + +// Collect some statistics from the database +$result = $db->query('SELECT COUNT(id) FROM '.$db->prefix.'users') or error('Unable to fetch total user count', __FILE__, __LINE__, $db->error()); +$stats['totalusers'] = $db->result($result, 0) - 1; // Minus the guest account + +$result = $db->query('SELECT id, username FROM '.$db->prefix.'users ORDER BY registered DESC LIMIT 1') or error('Unable to fetch newest registered user', __FILE__, __LINE__, $db->error()); +$stats['lastuser'] = $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['totaltopics'], $stats['totalposts']) = $db->fetch_row($result); + +?> +
 
+ +
 
+ + + + + +
+ + + + + +
+ 1) ? $lang_index['registered users'] : $lang_index['registered users']).', '.$stats['totaltopics'].' '.(($stats['totaltopics'] <> 1) ? $lang_index['topics'] : $lang_index['topic']).' '.$lang_index['and'].' '.$stats['totalposts'].' '.(($stats['totalposts'] <> 1) ? $lang_index['posts'] : $lang_index['post']) ?>.
+ . +query('SELECT user_id, ident, logged FROM '.$db->prefix.'online ORDER BY ident'); + if (!$result) { + throw new Exception('Unable to fetch online list: ' . $db->error()); + } + + while ($cur_user_online = $result->fetch_array(MYSQLI_ASSOC)) { + if ($cur_user_online['user_id'] > 0) { + $users[] = ''.htmlspecialchars($cur_user_online['ident']).''; + } else { + $num_guests++; + } + } + + $num_users = count($users); + + echo "\t\t\t\t\t\t".'
'.$lang_index['Currently serving'].' '.$num_users.' '.(($num_users != 1) ? $lang_index['registered users'] : $lang_index['registered user']).' '.$lang_index['and'].' '.$num_guests.' '.(($num_guests != 1) ? $lang_index['guests'] : $lang_index['guest']).'.'; + + if ($num_users) { + echo '

'."\n\t\t\t\t\t\t".implode(', ', $users)."\n"; + } else { + echo "\n"; + } +} + + +?> +
+ +
+
+ +
 
+here instead.'); + +// Make sure we are running at least PHP 4.2.0 +if (intval(str_replace('.', '', phpversion())) < 420) + exit('You are running PHP version '.phpversion().'. PunBB requires at least PHP 4.2.0 to run properly. You must upgrade your PHP installation before you can continue.'); + +// Disable error reporting for uninitialized variables +error_reporting(E_ERROR | E_WARNING | E_PARSE); + +// Turn off PHP time limit +@set_time_limit(0); + + +$punbb_version = '1.0'; + + +if (!isset($_POST['form_sent'])) +{ + +?> + + + + + +PunBB Installation + + + + + + + + + + + + +
Instructions
Welcome to PunBB installation! You are about to install PunBB . Please make sure that the database that PunBB will be installed into is already created. If you are uncertain about what to enter in the fields below consult your server administrator.
+ +
 
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Configuration
Database type   + The type of database this forum will be using.

+   +
Database server hostname   + The address of the database server (example: localhost, db.myhost.com or 192.168.0.15). You can specify a specific port number if your database doesn't run on the default port (example: localhost:3580).

+   +
Database name   + The name of the database that PunBB will be installed into.

+   +
Database username   + The username with which you connect to the database.

+   +
Database password   + The password with which you connect to the database.

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

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

+   +
Administrator password   + Passwords can be between 4 and 16 characters long. Passwords are case sensitive.

+  
+    Re-enter password to confirm. +
Administrator e-mail   + The e-mail address of the forum administrator.

+   +
Base URL   + The URL (without trailing slash) of your PunBB forum (example: http://forum.myhost.com or http://myhost.com/~myuser). This must be correct or administrators and moderators will not be able to submit any forms.

+   +
Language   + The language you want the forum to be displayed in.

+   +
Actions   +
  

+
+
+ + + +Go back.'); + if (strlen($password1) < 4) + exit('Passwords must be at least 4 characters long. Please go back and correct. Go back.'); + if ($password1 != $password2) + exit('Passwords do not match. Please go back and correct. Go back.'); + if (!strcasecmp($username, 'Guest')) + exit('The username guest is reserved. Please go back and correct. Go back.'); + if (preg_match('/[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}/', $username)) + exit('Usernames may not be in the form of an IP address. Please go back and correct. Go back.'); + if (preg_match('#\[b\]|\[/b\]|\[u\]|\[/u\]|\[i\]|\[/i\]|\[color|\[/color\]|\[quote\]|\[/quote\]|\[code\]|\[/code\]|\[img\]|\[/img\]|\[url|\[/url\]|\[email|\[/email\]#i', $username)) + exit('Usernames may not contain any of the text formatting tags (BBCode) that the forum uses. Go back.'); + + if (!preg_match('/^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,4})$/', $email)) + exit('The administrator e-mail address you entered is invalid. Please go back and correct. Go back.'); + + + // Load the appropriate DB layer class + switch ($db_type) + { + case 'mysql': + require 'include/dblayer/mysql.php'; + break; + + case 'pgsql': + require 'include/dblayer/pgsql.php'; + break; + + default: + exit('\''.$db_type.'\' is not a valid database type. Go back.'); + break; + } + + // Create the database object (and connect/select db) + $db = new DBLayer($db_host, $db_username, $db_password, $db_name, $db_prefix, false); + + + // Create all tables + switch ($db_type) + { + case 'mysql': + $sql = 'CREATE TABLE '.$db_prefix."bans ( + id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, + username VARCHAR(25) DEFAULT NULL, + ip VARCHAR(15) DEFAULT NULL, + email VARCHAR(50) DEFAULT NULL, + expire INT(10) UNSIGNED DEFAULT NULL, + PRIMARY KEY (id) + ) ENGINE=InnoDB;"; + break; + + case 'pgsql': + // This is a good time to start a transaction + $db->query('BEGIN') or exit('Unable to start transaction. Please check your settings and try again. Go back.'); + + $sql = 'CREATE TABLE '.$db_prefix."bans ( + id SERIAL, + username VARCHAR(25) DEFAULT NULL, + ip VARCHAR(15) DEFAULT NULL, + email VARCHAR(50) DEFAULT NULL, + expire INT DEFAULT NULL, + PRIMARY KEY (id) + )"; + break; + } + + $db->query($sql) or exit('Unable to create table '.$db_prefix.'bans. Please check your settings and try again. Go back.'); + + + + switch ($db_type) + { + case 'mysql': + $sql = 'CREATE TABLE '.$db_prefix."categories ( + id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, + cat_name VARCHAR(80) NOT NULL DEFAULT 'New Category', + admmod_only TINYINT(1) NOT NULL DEFAULT '0', + position INT(10) NOT NULL DEFAULT '0', + PRIMARY KEY (id) + ) ENGINE=InnoDB;"; + break; + + case 'pgsql': + $sql = 'CREATE TABLE '.$db_prefix."categories ( + id SERIAL, + cat_name VARCHAR(80) NOT NULL DEFAULT 'New Category', + admmod_only SMALLINT NOT NULL DEFAULT '0', + position INT NOT NULL DEFAULT '0', + PRIMARY KEY (id) + )"; + break; + } + + $db->query($sql) or exit('Unable to create table '.$db_prefix.'categories. Please check your settings and try again. Go back.'); + + + + switch ($db_type) + { + case 'mysql': + $sql = 'CREATE TABLE '.$db_prefix."censoring ( + id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, + search_for VARCHAR(60) NOT NULL DEFAULT '', + replace_with VARCHAR(60) NOT NULL DEFAULT '', + PRIMARY KEY (id) + ) ENGINE=InnoDB;"; + break; + + case 'pgsql': + $sql = 'CREATE TABLE '.$db_prefix."censoring ( + id SERIAL, + search_for VARCHAR(60) NOT NULL DEFAULT '', + replace_with VARCHAR(60) NOT NULL DEFAULT '', + PRIMARY KEY (id) + )"; + break; + } + + $db->query($sql) or exit('Unable to create table '.$db_prefix.'censoring. Please check your settings and try again. Go back.'); + + + + switch ($db_type) + { + case 'mysql': + $sql = 'CREATE TABLE '.$db_prefix."forums ( + id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, + forum_name VARCHAR(80) NOT NULL DEFAULT 'New forum', + forum_desc TEXT DEFAULT NULL, + moderators TEXT DEFAULT NULL, + num_topics MEDIUMINT(8) UNSIGNED NOT NULL DEFAULT '0', + num_posts MEDIUMINT(8) UNSIGNED NOT NULL DEFAULT '0', + last_post INT(10) UNSIGNED DEFAULT NULL, + last_post_id INT(10) UNSIGNED DEFAULT NULL, + last_poster VARCHAR(25) DEFAULT NULL, + closed TINYINT(1) NOT NULL DEFAULT '0', + admmod_only TINYINT(1) NOT NULL DEFAULT '0', + position INT(10) NOT NULL DEFAULT '0', + cat_id INT(10) UNSIGNED NOT NULL DEFAULT '0', + PRIMARY KEY (id) + ) ENGINE=InnoDB;"; + break; + + case 'pgsql': + $sql = 'CREATE TABLE '.$db_prefix."forums ( + id SERIAL, + forum_name VARCHAR(80) NOT NULL DEFAULT 'New forum', + forum_desc TEXT DEFAULT NULL, + moderators TEXT DEFAULT NULL, + num_topics INT NOT NULL DEFAULT '0', + num_posts INT NOT NULL DEFAULT '0', + last_post INT DEFAULT NULL, + last_post_id INT DEFAULT NULL, + last_poster VARCHAR(25) DEFAULT NULL, + closed SMALLINT NOT NULL DEFAULT '0', + admmod_only SMALLINT NOT NULL DEFAULT '0', + position INT NOT NULL DEFAULT '0', + cat_id INT NOT NULL DEFAULT '0', + PRIMARY KEY (id) + )"; + break; + } + + $db->query($sql) or exit('Unable to create table '.$db_prefix.'forums. Please check your settings and try again. Go back.'); + + + + switch ($db_type) + { + case 'mysql': + $sql = 'CREATE TABLE '.$db_prefix."online ( + user_id INT(10) UNSIGNED NOT NULL DEFAULT '0', + ident VARCHAR(25) NOT NULL DEFAULT '', + logged INT(10) UNSIGNED NOT NULL DEFAULT '0' + ) ENGINE=MEMORY;"; + break; + + case 'pgsql': + $sql = 'CREATE TABLE '.$db_prefix."online ( + user_id INT NOT NULL DEFAULT '0', + ident VARCHAR(25) NOT NULL DEFAULT '', + logged INT NOT NULL DEFAULT '0' + )"; + break; + } + + $db->query($sql) or exit('Unable to create table '.$db_prefix.'online. Please check your settings and try again. Go back.'); + + + + switch ($db_type) + { + case 'mysql': + $sql = 'CREATE TABLE '.$db_prefix."options ( + cur_version VARCHAR(30) NOT NULL DEFAULT '', + board_title TEXT NOT NULL DEFAULT '', + board_desc TEXT DEFAULT NULL, + server_timezone TINYINT(2) NOT NULL DEFAULT '0', + time_format VARCHAR(15) NOT NULL DEFAULT 'H:i:s', + date_format VARCHAR(15) NOT NULL DEFAULT 'Y-m-d', + timeout_cookie SMALLINT(6) NOT NULL DEFAULT '600', + timeout_online SMALLINT(6) NOT NULL DEFAULT '300', + redirect_delay TINYINT(3) NOT NULL DEFAULT '1', + flood_interval SMALLINT(5) UNSIGNED NOT NULL DEFAULT '30', + smilies TINYINT(1) NOT NULL DEFAULT '1', + smilies_sig TINYINT(1) NOT NULL DEFAULT '1', + make_links TINYINT(1) NOT NULL DEFAULT '1', + show_post_count TINYINT(1) NOT NULL DEFAULT '1', + default_style VARCHAR(25) NOT NULL DEFAULT 'Oxygen', + topic_review TINYINT(3) NOT NULL DEFAULT '15', + disp_topics_default TINYINT(3) NOT NULL DEFAULT '30', + disp_posts_default TINYINT(3) NOT NULL DEFAULT '25', + indent_num_spaces TINYINT(3) NOT NULL DEFAULT '4', + quickpost TINYINT(1) NOT NULL DEFAULT '1', + users_online TINYINT(1) NOT NULL DEFAULT '1', + censoring TINYINT(1) NOT NULL DEFAULT '0', + ranks TINYINT(1) NOT NULL DEFAULT '1', + show_dot TINYINT(1) NOT NULL DEFAULT '0', + quickjump TINYINT(1) NOT NULL DEFAULT '1', + gzip TINYINT(1) NOT NULL DEFAULT '0', + report_method TINYINT(1) NOT NULL DEFAULT '0', + mailing_list TEXT DEFAULT NULL, + avatars TINYINT(1) NOT NULL DEFAULT '1', + avatars_dir VARCHAR(50) NOT NULL DEFAULT 'img/avatars', + avatars_width SMALLINT(5) UNSIGNED NOT NULL DEFAULT '60', + avatars_height SMALLINT(5) UNSIGNED NOT NULL DEFAULT '60', + avatars_size SMALLINT(5) UNSIGNED NOT NULL DEFAULT '10240', + search TINYINT(1) NOT NULL DEFAULT '1', + search_all_forums TINYINT(1) NOT NULL DEFAULT '1', + base_url VARCHAR(100) NOT NULL DEFAULT '', + admin_email VARCHAR(50) NOT NULL DEFAULT '', + webmaster_email VARCHAR(50) NOT NULL DEFAULT '', + subscriptions TINYINT(1) NOT NULL DEFAULT '1', + smtp_host VARCHAR(100) DEFAULT NULL, + smtp_user VARCHAR(25) DEFAULT NULL, + smtp_pass VARCHAR(25) DEFAULT NULL, + regs_allow TINYINT(1) NOT NULL DEFAULT '1', + regs_validate TINYINT(1) NOT NULL DEFAULT '0', + rules TINYINT(1) NOT NULL DEFAULT '0', + rules_message TEXT DEFAULT NULL, + maintenance TINYINT(1) NOT NULL DEFAULT '0', + maintenance_message TEXT DEFAULT NULL + ) ENGINE=InnoDB;"; + break; + + case 'pgsql': + $sql = 'CREATE TABLE '.$db_prefix."options ( + cur_version VARCHAR(30) NOT NULL DEFAULT '', + board_title VARCHAR(255) NOT NULL DEFAULT '', + board_desc VARCHAR(255) DEFAULT NULL, + server_timezone SMALLINT NOT NULL DEFAULT '0', + time_format VARCHAR(15) NOT NULL DEFAULT 'H:i:s', + date_format VARCHAR(15) NOT NULL DEFAULT 'Y-m-d', + timeout_cookie SMALLINT NOT NULL DEFAULT '600', + timeout_online SMALLINT NOT NULL DEFAULT '300', + redirect_delay SMALLINT NOT NULL DEFAULT '1', + flood_interval SMALLINT NOT NULL DEFAULT '30', + smilies SMALLINT NOT NULL DEFAULT '1', + smilies_sig SMALLINT NOT NULL DEFAULT '1', + make_links SMALLINT NOT NULL DEFAULT '1', + show_post_count SMALLINT NOT NULL DEFAULT '1', + default_style VARCHAR(25) NOT NULL DEFAULT 'Oxygen', + topic_review SMALLINT NOT NULL DEFAULT '15', + disp_topics_default SMALLINT NOT NULL DEFAULT '30', + disp_posts_default SMALLINT NOT NULL DEFAULT '25', + indent_num_spaces SMALLINT NOT NULL DEFAULT '4', + quickpost SMALLINT NOT NULL DEFAULT '1', + users_online SMALLINT NOT NULL DEFAULT '1', + censoring SMALLINT NOT NULL DEFAULT '0', + ranks SMALLINT NOT NULL DEFAULT '1', + show_dot SMALLINT NOT NULL DEFAULT '0', + quickjump SMALLINT NOT NULL DEFAULT '1', + gzip SMALLINT NOT NULL DEFAULT '0', + report_method SMALLINT NOT NULL DEFAULT '0', + mailing_list TEXT DEFAULT NULL, + avatars SMALLINT NOT NULL DEFAULT '1', + avatars_dir VARCHAR(50) NOT NULL DEFAULT 'img/avatars', + avatars_width SMALLINT NOT NULL DEFAULT '60', + avatars_height SMALLINT NOT NULL DEFAULT '60', + avatars_size SMALLINT NOT NULL DEFAULT '10240', + search SMALLINT NOT NULL DEFAULT '1', + search_all_forums SMALLINT NOT NULL DEFAULT '1', + base_url VARCHAR(100) NOT NULL DEFAULT '', + admin_email VARCHAR(50) NOT NULL DEFAULT '', + webmaster_email VARCHAR(50) NOT NULL DEFAULT '', + subscriptions SMALLINT NOT NULL DEFAULT '1', + smtp_host VARCHAR(100) DEFAULT NULL, + smtp_user VARCHAR(25) DEFAULT NULL, + smtp_pass VARCHAR(25) DEFAULT NULL, + regs_allow SMALLINT NOT NULL DEFAULT '1', + regs_validate SMALLINT NOT NULL DEFAULT '0', + rules SMALLINT NOT NULL DEFAULT '0', + rules_message TEXT DEFAULT NULL, + maintenance SMALLINT NOT NULL DEFAULT '0', + maintenance_message TEXT DEFAULT NULL + )"; + break; + } + + $db->query($sql) or exit('Unable to create table '.$db_prefix.'options. Please check your settings and try again. Go back.'); + + + + switch ($db_type) + { + case 'mysql': + $sql = 'CREATE TABLE '.$db_prefix."permissions ( + guests_read TINYINT(1) NOT NULL DEFAULT '1', + guests_post TINYINT(1) NOT NULL DEFAULT '1', + guests_post_topic TINYINT(1) NOT NULL DEFAULT '1', + guests_search TINYINT(1) NOT NULL DEFAULT '1', + users_post TINYINT(1) NOT NULL DEFAULT '1', + users_post_topic TINYINT(1) NOT NULL DEFAULT '1', + users_edit_post TINYINT(1) NOT NULL DEFAULT '1', + users_del_post TINYINT(1) NOT NULL DEFAULT '1', + users_del_topic TINYINT(1) NOT NULL DEFAULT '1', + users_set_title TINYINT(1) NOT NULL DEFAULT '0', + message_html TINYINT(1) NOT NULL DEFAULT '0', + message_bbcode TINYINT(1) NOT NULL DEFAULT '1', + message_img_tag TINYINT(1) NOT NULL DEFAULT '1', + message_all_caps TINYINT(1) NOT NULL DEFAULT '0', + subject_all_caps TINYINT(1) NOT NULL DEFAULT '0', + sig_all_caps TINYINT(1) NOT NULL DEFAULT '0', + sig_html TINYINT(1) NOT NULL DEFAULT '0', + sig_bbcode TINYINT(1) NOT NULL DEFAULT '1', + sig_img_tag TINYINT(1) NOT NULL DEFAULT '0', + sig_length SMALLINT(5) NOT NULL DEFAULT '400', + sig_lines TINYINT(3) NOT NULL DEFAULT '4', + allow_banned_email TINYINT(1) NOT NULL DEFAULT '1', + allow_dupe_email TINYINT(1) NOT NULL DEFAULT '0' + ) ENGINE=InnoDB;"; + break; + + case 'pgsql': + $sql = 'CREATE TABLE '.$db_prefix."permissions ( + guests_read SMALLINT NOT NULL DEFAULT '1', + guests_post SMALLINT NOT NULL DEFAULT '1', + guests_post_topic SMALLINT NOT NULL DEFAULT '1', + guests_search SMALLINT NOT NULL DEFAULT '1', + users_post SMALLINT NOT NULL DEFAULT '1', + users_post_topic SMALLINT NOT NULL DEFAULT '1', + users_edit_post SMALLINT NOT NULL DEFAULT '1', + users_del_post SMALLINT NOT NULL DEFAULT '1', + users_del_topic SMALLINT NOT NULL DEFAULT '1', + users_set_title SMALLINT NOT NULL DEFAULT '0', + message_html SMALLINT NOT NULL DEFAULT '0', + message_bbcode SMALLINT NOT NULL DEFAULT '1', + message_img_tag SMALLINT NOT NULL DEFAULT '1', + message_all_caps SMALLINT NOT NULL DEFAULT '0', + subject_all_caps SMALLINT NOT NULL DEFAULT '0', + sig_all_caps SMALLINT NOT NULL DEFAULT '0', + sig_html SMALLINT NOT NULL DEFAULT '0', + sig_bbcode SMALLINT NOT NULL DEFAULT '1', + sig_img_tag SMALLINT NOT NULL DEFAULT '0', + sig_length SMALLINT NOT NULL DEFAULT '400', + sig_lines SMALLINT NOT NULL DEFAULT '4', + allow_banned_email SMALLINT NOT NULL DEFAULT '1', + allow_dupe_email SMALLINT NOT NULL DEFAULT '0' + )"; + break; + } + + $db->query($sql) or exit('Unable to create table '.$db_prefix.'permissions. Please check your settings and try again. Go back.'); + + + + switch ($db_type) + { + case 'mysql': + $sql = 'CREATE TABLE '.$db_prefix."posts ( + id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, + poster VARCHAR(25) NOT NULL DEFAULT '', + poster_id INT(10) UNSIGNED NOT NULL DEFAULT '1', + poster_ip VARCHAR(15) DEFAULT NULL, + poster_email VARCHAR(50) DEFAULT NULL, + message TEXT NOT NULL DEFAULT '', + smilies TINYINT(1) NOT NULL DEFAULT '1', + posted INT(10) UNSIGNED NOT NULL DEFAULT '0', + edited INT(10) UNSIGNED DEFAULT NULL, + edited_by VARCHAR(25) DEFAULT NULL, + topic_id INT(10) UNSIGNED NOT NULL DEFAULT '0', + PRIMARY KEY (id) + ) ENGINE=InnoDB;"; + break; + + case 'pgsql': + $sql = 'CREATE TABLE '.$db_prefix."posts ( + id SERIAL, + poster VARCHAR(25) NOT NULL DEFAULT '', + poster_id INT NOT NULL DEFAULT '1', + poster_ip VARCHAR(15) DEFAULT NULL, + poster_email VARCHAR(50) DEFAULT NULL, + message TEXT NOT NULL DEFAULT '', + smilies SMALLINT NOT NULL DEFAULT '1', + posted INT NOT NULL DEFAULT '0', + edited INT DEFAULT NULL, + edited_by VARCHAR(25) DEFAULT NULL, + topic_id INT NOT NULL DEFAULT '0', + PRIMARY KEY (id) + )"; + break; + } + + $db->query($sql) or exit('Unable to create table '.$db_prefix.'posts. Please check your settings and try again. Go back.'); + + + + switch ($db_type) + { + case 'mysql': + $sql = 'CREATE TABLE '.$db_prefix."ranks ( + id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, + rank VARCHAR(50) NOT NULL DEFAULT '', + min_posts MEDIUMINT(8) UNSIGNED NOT NULL DEFAULT '0', + PRIMARY KEY (id) + ) ENGINE=InnoDB;"; + break; + + case 'pgsql': + $sql = 'CREATE TABLE '.$db_prefix."ranks ( + id SERIAL, + rank VARCHAR(50) NOT NULL DEFAULT '', + min_posts INT NOT NULL DEFAULT '0', + PRIMARY KEY (id) + )"; + break; + } + + $db->query($sql) or exit('Unable to create table '.$db_prefix.'titles. Please check your settings and try again. Go back.'); + + + + switch ($db_type) + { + case 'mysql': + $sql = 'CREATE TABLE '.$db_prefix."reports ( + id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, + post_id int(10) UNSIGNED NOT NULL DEFAULT '0', + topic_id int(10) UNSIGNED NOT NULL DEFAULT '0', + forum_id int(10) UNSIGNED NOT NULL DEFAULT '0', + reported_by int(10) UNSIGNED NOT NULL DEFAULT '0', + created int(10) UNSIGNED NOT NULL DEFAULT '0', + message text NOT NULL DEFAULT '', + zapped int(10) UNSIGNED DEFAULT NULL, + zapped_by int(10) UNSIGNED DEFAULT NULL, + PRIMARY KEY (id) + ) ENGINE=InnoDB;"; + break; + + case 'pgsql': + $sql = 'CREATE TABLE '.$db_prefix."reports ( + id SERIAL, + post_id INT NOT NULL DEFAULT '0', + topic_id INT NOT NULL DEFAULT '0', + forum_id INT NOT NULL DEFAULT '0', + reported_by INT NOT NULL DEFAULT '0', + created INT NOT NULL DEFAULT '0', + message TEXT NOT NULL DEFAULT '', + zapped INT DEFAULT NULL, + zapped_by INT DEFAULT NULL, + PRIMARY KEY (id) + )"; + break; + } + + $db->query($sql) or exit('Unable to create table '.$db_prefix.'reports. Please check your settings and try again. Go back.'); + + + + switch ($db_type) + { + case 'mysql': + $sql = 'CREATE TABLE '.$db_prefix."search_matches ( + post_id INT(10) UNSIGNED NOT NULL DEFAULT '0', + word_id INT(10) UNSIGNED NOT NULL DEFAULT '0', + subject_match TINYINT(1) NOT NULL DEFAULT '0' + ) ENGINE=InnoDB;"; + break; + + case 'pgsql': + $sql = 'CREATE TABLE '.$db_prefix."search_matches ( + post_id INT NOT NULL DEFAULT '0', + word_id INT NOT NULL DEFAULT '0', + subject_match SMALLINT NOT NULL DEFAULT '0' + )"; + break; + } + + $db->query($sql) or exit('Unable to create table '.$db_prefix.'search_matches. Please check your settings and try again. Go back.'); + + + + switch ($db_type) + { + case 'mysql': + $sql = 'CREATE TABLE '.$db_prefix."search_results ( + id INT(10) UNSIGNED NOT NULL DEFAULT '0', + ident VARCHAR(25) NOT NULL DEFAULT '', + search_data TEXT NOT NULL, + PRIMARY KEY (id) + ) ENGINE=InnoDB;"; + break; + + case 'pgsql': + $sql = 'CREATE TABLE '.$db_prefix."search_results ( + id INT NOT NULL DEFAULT '0', + ident VARCHAR(25) NOT NULL DEFAULT '', + search_data TEXT NOT NULL, + PRIMARY KEY (id) + )"; + break; + } + + $db->query($sql) or exit('Unable to create table '.$db_prefix.'search_results. Please check your settings and try again. Go back.'); + + + + switch ($db_type) + { + case 'mysql': + $sql = 'CREATE TABLE '.$db_prefix."search_words ( + id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, + word VARCHAR(20) BINARY NOT NULL DEFAULT '', + PRIMARY KEY (word), + KEY ".$db_prefix."search_words_id_idx (id) + ) ENGINE=InnoDB;"; + break; + + case 'pgsql': + $sql = 'CREATE TABLE '.$db_prefix."search_words ( + id SERIAL, + word VARCHAR(20) NOT NULL DEFAULT '', + PRIMARY KEY (word) + )"; + break; + } + + $db->query($sql) or exit('Unable to create table '.$db_prefix.'search_words. Please check your settings and try again. Go back.'); + + + + switch ($db_type) + { + case 'mysql': + $sql = 'CREATE TABLE '.$db_prefix."topics ( + id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, + poster VARCHAR(25) NOT NULL DEFAULT '', + subject VARCHAR(70) NOT NULL DEFAULT '', + posted INT(10) UNSIGNED NOT NULL DEFAULT '0', + last_post INT(10) UNSIGNED NOT NULL DEFAULT '0', + last_post_id INT(10) UNSIGNED NOT NULL DEFAULT '0', + last_poster VARCHAR(25) DEFAULT NULL, + subscribers TEXT DEFAULT NULL, + num_views MEDIUMINT(8) UNSIGNED NOT NULL DEFAULT '0', + num_replies MEDIUMINT(8) UNSIGNED NOT NULL DEFAULT '0', + closed TINYINT(1) NOT NULL DEFAULT '0', + sticky TINYINT(1) NOT NULL DEFAULT '0', + moved_to INT(10) UNSIGNED DEFAULT NULL, + forum_id INT(10) UNSIGNED NOT NULL DEFAULT '0', + PRIMARY KEY (id) + ) ENGINE=InnoDB;"; + break; + + case 'pgsql': + $sql = 'CREATE TABLE '.$db_prefix."topics ( + id SERIAL, + poster VARCHAR(25) NOT NULL DEFAULT '', + subject VARCHAR(70) NOT NULL DEFAULT '', + posted INT NOT NULL DEFAULT '0', + last_post INT NOT NULL DEFAULT '0', + last_post_id INT NOT NULL DEFAULT '0', + last_poster VARCHAR(25) DEFAULT NULL, + subscribers TEXT DEFAULT NULL, + num_views INT NOT NULL DEFAULT '0', + num_replies INT NOT NULL DEFAULT '0', + closed SMALLINT NOT NULL DEFAULT '0', + sticky SMALLINT NOT NULL DEFAULT '0', + moved_to INT DEFAULT NULL, + forum_id INT NOT NULL DEFAULT '0', + PRIMARY KEY (id) + )"; + break; + } + + $db->query($sql) or exit('Unable to create table '.$db_prefix.'topics. Please check your settings and try again. Go back.'); + + + + switch ($db_type) + { + case 'mysql': + $sql = 'CREATE TABLE '.$db_prefix."users ( + id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, + username VARCHAR(25) NOT NULL DEFAULT '', + password VARCHAR(32) NOT NULL DEFAULT '', + email VARCHAR(50) NOT NULL DEFAULT '', + title VARCHAR(50) DEFAULT NULL, + realname VARCHAR(40) DEFAULT NULL, + url VARCHAR(100) DEFAULT NULL, + icq VARCHAR(12) DEFAULT NULL, + aim VARCHAR(20) DEFAULT NULL, + yahoo VARCHAR(20) DEFAULT NULL, + location VARCHAR(30) DEFAULT NULL, + use_avatar TINYINT(1) NOT NULL DEFAULT '0', + signature TEXT DEFAULT NULL, + disp_topics TINYINT(3) UNSIGNED DEFAULT NULL, + disp_posts TINYINT(3) UNSIGNED DEFAULT NULL, + hide_email TINYINT(1) NOT NULL DEFAULT '0', + save_pass TINYINT(1) NOT NULL DEFAULT '1', + smilies TINYINT(1) NOT NULL DEFAULT '1', + show_img TINYINT(1) NOT NULL DEFAULT '1', + show_sig TINYINT(1) NOT NULL DEFAULT '1', + link_to_new_win TINYINT(1) NOT NULL DEFAULT '1', + timezone TINYINT(2) NOT NULL DEFAULT '0', + style VARCHAR(25) NOT NULL DEFAULT 'Oxygen', + num_posts INT(10) UNSIGNED NOT NULL DEFAULT '0', + status TINYINT(1) NOT NULL DEFAULT '-1', + last_post INT(10) UNSIGNED DEFAULT NULL, + registered INT(10) UNSIGNED NOT NULL DEFAULT '0', + admin_note VARCHAR(30) DEFAULT NULL, + activate_string VARCHAR(50) DEFAULT NULL, + activate_key VARCHAR(8) DEFAULT NULL, + PRIMARY KEY (id) + ) ENGINE=InnoDB;"; + break; + + case 'pgsql': + $sql = 'CREATE TABLE '.$db_prefix."users ( + id SERIAL, + username VARCHAR(25) NOT NULL DEFAULT '', + password VARCHAR(32) NOT NULL DEFAULT '', + email VARCHAR(50) NOT NULL DEFAULT '', + title VARCHAR(50) DEFAULT NULL, + realname VARCHAR(40) DEFAULT NULL, + url VARCHAR(100) DEFAULT NULL, + icq VARCHAR(12) DEFAULT NULL, + aim VARCHAR(20) DEFAULT NULL, + yahoo VARCHAR(20) DEFAULT NULL, + location VARCHAR(30) DEFAULT NULL, + use_avatar SMALLINT NOT NULL DEFAULT '0', + signature TEXT DEFAULT NULL, + disp_topics SMALLINT DEFAULT NULL, + disp_posts SMALLINT DEFAULT NULL, + hide_email SMALLINT NOT NULL DEFAULT '0', + save_pass SMALLINT NOT NULL DEFAULT '1', + smilies SMALLINT NOT NULL DEFAULT '1', + show_img SMALLINT NOT NULL DEFAULT '1', + show_sig SMALLINT NOT NULL DEFAULT '1', + link_to_new_win SMALLINT NOT NULL DEFAULT '1', + timezone SMALLINT NOT NULL DEFAULT '0', + style VARCHAR(25) NOT NULL DEFAULT 'Oxygen', + num_posts INT NOT NULL DEFAULT '0', + status SMALLINT NOT NULL DEFAULT '-1', + last_post INT DEFAULT NULL, + registered INT NOT NULL DEFAULT '0', + admin_note VARCHAR(30) DEFAULT NULL, + activate_string VARCHAR(50) DEFAULT NULL, + activate_key VARCHAR(8) DEFAULT NULL, + PRIMARY KEY (id) + )"; + break; + } + + $db->query($sql) or exit('Unable to create table '.$db_prefix.'users. Please check your settings and try again. Go back.'); + + + // Add a few indexes + $queries[] = 'CREATE INDEX '.$db_prefix.'posts_topic_id_idx ON '.$db_prefix.'posts(topic_id)'; + $queries[] = 'CREATE INDEX '.$db_prefix.'posts_poster_id_idx ON '.$db_prefix.'posts(poster_id)'; + $queries[] = 'CREATE INDEX '.$db_prefix.'reports_zapped_idx ON '.$db_prefix.'reports(zapped)'; + $queries[] = 'CREATE INDEX '.$db_prefix.'search_matches_word_id_idx ON '.$db_prefix.'search_matches(word_id)'; + $queries[] = 'CREATE INDEX '.$db_prefix.'search_matches_post_id_idx ON '.$db_prefix.'search_matches(post_id)'; + $queries[] = 'CREATE INDEX '.$db_prefix.'search_results_ident_idx ON '.$db_prefix.'search_results(ident)'; + $queries[] = 'CREATE INDEX '.$db_prefix.'topics_forum_id_idx ON '.$db_prefix.'topics(forum_id)'; + $queries[] = 'CREATE INDEX '.$db_prefix.'users_registered_idx ON '.$db_prefix.'users(registered)'; + + // Special cases + switch ($db_type) + { + case 'mysql': + $queries[] = 'CREATE INDEX '.$db_prefix.'users_username_idx ON '.$db_prefix.'users(username(3))'; + break; + + case 'pgsql': + $queries[] = 'CREATE INDEX '.$db_prefix.'users_username_idx ON '.$db_prefix.'users(username)'; + $queries[] = 'CREATE INDEX '.$db_prefix.'search_words_id_idx ON '.$db_prefix.'search_words(id)'; + + // PostgreSQL <7.3 note + // Remove the next 10 rows if running PostgreSQL 7.2 or earlier + $queries[] = 'CREATE INDEX '.$db_prefix.'bans_id_idx ON '.$db_prefix.'bans(id)'; + $queries[] = 'CREATE INDEX '.$db_prefix.'categories_id_idx ON '.$db_prefix.'categories(id)'; + $queries[] = 'CREATE INDEX '.$db_prefix.'censoring_id_idx ON '.$db_prefix.'censoring(id)'; + $queries[] = 'CREATE INDEX '.$db_prefix.'forums_id_idx ON '.$db_prefix.'forums(id)'; + $queries[] = 'CREATE INDEX '.$db_prefix.'posts_id_idx ON '.$db_prefix.'posts(id)'; + $queries[] = 'CREATE INDEX '.$db_prefix.'ranks_id_idx ON '.$db_prefix.'ranks(id)'; + $queries[] = 'CREATE INDEX '.$db_prefix.'reports_id_idx ON '.$db_prefix.'reports(id)'; + $queries[] = 'CREATE INDEX '.$db_prefix.'search_results_id_idx ON '.$db_prefix.'search_results(id)'; + $queries[] = 'CREATE INDEX '.$db_prefix.'topics_id_idx ON '.$db_prefix.'topics(id)'; + $queries[] = 'CREATE INDEX '.$db_prefix.'users_id_idx ON '.$db_prefix.'users(id)'; + break; + } + + @reset($queries); + foreach ($queries as $sql) + $db->query($sql) or exit('Unable to create indexes. Please check your configuration and try again. Go back.'); + + + + $now = time(); + + // Insert some default values (start transaction) + $db->query('INSERT INTO '.$db_prefix."options (cur_version, board_title, board_desc, base_url, admin_email, webmaster_email, mailing_list, rules_message, maintenance_message) VALUES('$punbb_version', 'My PunBB forum', 'Unfortunately no one can be told what PunBB is - you have to see it for yourself.', '$base_url', '$email', '$email', '$email', 'Enter your rules here.', 'The forums are temporarily down for maintenance. Please try again in a few minutes.\n\n/Administrator')", 1) + or exit('Unable to insert into table '.$db_prefix.'options. Please check your configuration and try again. Go back.'); + + $db->query('INSERT INTO '.$db_prefix."permissions (message_html) VALUES(0)") + or exit('Unable to insert into table '.$db_prefix.'permissions. Please check your configuration and try again. Go back.'); + + $db->query('INSERT INTO '.$db_prefix."users (username, password, email) VALUES('Guest', 'Guest', 'Guest')") + or exit('Unable to insert into table '.$db_prefix.'users. Please check your configuration and try again. Go back.'); + + $db->query('INSERT INTO '.$db_prefix."users (username, password, email, num_posts, status, registered) VALUES('".addslashes($username)."', '".md5($password1)."', '$email', 1, 2, ".$now.')') + or exit('Unable to insert into table '.$db_prefix.'users. Please check your configuration and try again. Go back.'); + + $db->query('INSERT INTO '.$db_prefix."categories (cat_name, position) VALUES('Test category', 1)") + or exit('Unable to insert into table '.$db_prefix.'categories. Please check your configuration and try again. Go back.'); + + $db->query('INSERT INTO '.$db_prefix."forums (forum_name, forum_desc, num_topics, num_posts, last_post, last_post_id, last_poster, position, cat_id) VALUES('Test forum', 'This is just a test forum', 1, 1, ".$now.", 1, '".addslashes($username)."', 1, 1)") + or exit('Unable to insert into table '.$db_prefix.'forums. Please check your configuration and try again. Go back.'); + + $db->query('INSERT INTO '.$db_prefix."topics (poster, subject, posted, last_post, last_post_id, last_poster, forum_id) VALUES('".addslashes($username)."', 'Test post', ".$now.", ".$now.", 1, '".addslashes($username)."', 1)") + or exit('Unable to insert into table '.$db_prefix.'topics. Please check your configuration and try again. Go back.'); + + $db->query('INSERT INTO '.$db_prefix."posts (poster, poster_id, poster_ip, message, posted, topic_id) VALUES('".addslashes($username)."', 2, '127.0.0.1', 'If you are looking at this (which I guess you are), the install of PunBB appears to have worked! Now log in and head over to the administration control panel to configure your forum.', ".$now.', 1)') + or exit('Unable to insert into table '.$db_prefix.'posts. Please check your configuration and try again. Go back.'); + + $db->query('INSERT INTO '.$db_prefix."ranks (rank, min_posts) VALUES('New member', 0)") + or exit('Unable to insert into table '.$db_prefix.'titles. Please check your configuration and try again. Go back.'); + + $db->query('INSERT INTO '.$db_prefix."ranks (rank, min_posts) VALUES('Member', 10)", 2) // end transaction + or exit('Unable to insert into table '.$db_prefix.'titles. Please check your configuration and try again. Go back.'); + + + + // Check if default avatar directory is writable + if (!@is_writable('img/avatars/')) + $avatar_alert = '

The default directory for avatars (img/avatars) is currently not writable! If you want users to be able to upload their own avatar images you must see to it that the avatar directory is writable by PHP. You can later choose to save avatar images in a different directory (see Admin/Options).'; + + + /// Display config.php and give further instructions + $config = ' + + + + + +PunBB Installation + + + + + + + + + + + +
Final instructions
To finalize the installation all you need to do is to copy and paste the text in the text box below into a file called config.php and then upload this file to the root directory of your PunBB installation. You can later edit config.php if you reconfigure your setup (i.e. install a new language pack or change the database password).
+ +
 
+ + + + + + + + + + + + + +
config.php
File contents   
Info   +
Once you have created config.php with the contents above, PunBB is installed!

+ Go to forum index. +

+
+ + + + 'LTR', +'lang_encoding' => 'iso-8859-1', + +// Notices +'Bad request' => 'Bad request. The link you followed is incorrect or outdated.', +'No permission' => 'You do not have permission to access this page.', +'Bad referer' => 'Bad referer. You were referred to this page from an unauthorized source. Please go back and try again. 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.', + +// Miscellaneous (used in many scripts) +'Options' => 'Options', +'Actions' => 'Actions', +'Submit' => 'Submit', // "name" of submit buttons +'Banned message' => 'You are banned from this forum. If you have any questions you can contact the forum administrator at', +'Never' => 'Never', +'Today' => 'Today', +'Yesterday' => 'Yesterday', +'First page' => 'First page', +'Last page' => 'Last page', +'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)', +'Login required' => 'Only logged in users are allowed to read this forum.', +'Login' => 'Login', +'or' => 'or', +'register' => 'register', +'on' => 'on', // as in "BBCode is on" +'off' => 'off', +'Invalid e-mail' => 'The e-mail address you entered is invalid.', +'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 +'Username' => 'Username', +'E-mail' => 'E-mail', +'Registered' => 'Registered', +'Message' => 'Message', +'Topic' => 'Topic', +'Forum' => 'Forum', +'Posts' => 'Posts', +'Replies' => 'Replies', +'Author' => 'Author', +'Pages' => 'Pages', +'and' => 'and', + +// Title +'Title' => 'Title', +'Member' => 'Member', // Default title +'Moderator' => 'Moderator', +'Administrator' => 'Administrator', +'Banned' => 'Banned', +'Guest' => 'Guest', + +// Stuff for include/parser.php +'BBCode error' => 'The BBCode syntax in the message is incorrect.', +'BBCode error 1' => 'Missing start tag for [/quote].', +'BBCode error 2' => 'Missing end tag for [code].', +'BBCode error 3' => 'Missing start tag for [/code].', +'BBCode error 4' => 'Missing one or more end tags for [quote].', +'BBCode error 5' => 'Missing one or more start tags for [/quote].', + +// Stuff for the navigator (top of every page) +'Home' => 'Home', +'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' => 'Admin', +'Last visit' => 'Last visit', + +// Stuff for the page footer +'Show new posts' => 'Show new posts since last visit', +'Show unanswered posts' => 'Show unanswered posts', +'Show your posts' => 'Show your posts', +'Mark all as read' => 'Mark all forums as read', +'Jump to' => 'Jump to', +'Go' => ' Go ', // submit button in forum jump +'Move topic' => 'Move topic', +'Open topic' => 'Open topic', +'Close topic' => 'Close topic', +'Unstick topic' => 'Unstick topic', +'Stick topic' => 'Stick topic', +'Edit subscribers' => 'Edit subscribers' + +); + +$lang_direction = 'LTR'; +$lang_encoding = 'iso-8859-1'; diff --git a/lang/en/en_delete.php b/lang/en/en_delete.php new file mode 100644 index 0000000..de67777 --- /dev/null +++ b/lang/en/en_delete.php @@ -0,0 +1,12 @@ + 'Delete post', +'Warning' => 'Warning! If this is the first post in the topic, the whole topic will be deleted.', +'Delete' => 'Delete', // The submit button +'Post del redirect' => 'Post deleted. Redirecting ...', +'Topic del redirect' => 'Topic deleted. Redirecting ...' + +); diff --git a/lang/en/en_edit.php b/lang/en/en_edit.php new file mode 100644 index 0000000..a3bc7d9 --- /dev/null +++ b/lang/en/en_edit.php @@ -0,0 +1,21 @@ + 'Topics must contain a subject.', +'Too long subject' => 'Subjects cannot be longer than 70 characters.', +'No caps subject' => 'Subjects must not contain only capital letters and special characters in this forum.', +'No message' => 'You must enter a message.', +'Too long message' => 'Posts cannot be longer that 65535 characters (64 Kb).', +'No caps message' => 'Messages must not contain only capital letters and special characters in this forum.', + +// Miscellaneous +'Show smilies' => 'Show smilies', +'Silent edit' => 'Silent edit (don\'t display "Edited by ..." in topic view)', +'Edit message' => 'Edit message', +'Subject' => 'Subject', +'Edit redirect' => 'Post updated. Redirecting ...' + +); diff --git a/lang/en/en_forum.php b/lang/en/en_forum.php new file mode 100644 index 0000000..19dc4dc --- /dev/null +++ b/lang/en/en_forum.php @@ -0,0 +1,14 @@ + 'Post new topic', +'Forum closed' => 'Forum closed', +'Moderated by' => 'Moderated by', +'Views' => 'Views', +'Moved' => 'Moved', +'Sticky' => 'Sticky', +'Empty forum' => 'Forum is empty.' + +); diff --git a/lang/en/en_help.php b/lang/en/en_help.php new file mode 100644 index 0000000..6b72ad4 --- /dev/null +++ b/lang/en/en_help.php @@ -0,0 +1,41 @@ + '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', + +'Links and images' => 'Links and images', +'Links info' => 'You can create links to other documents or to e-mail adresses using the following tags:', +'My e-mail address' => 'My e-mail address', +'Images info' => 'If you want to display an image you can use the img tag:', + +'Quotes and code' => 'Quotes and code', +'Quotes info' => 'If you want to quote someone, you should use the quote tag:', +'Quote text' => 'This is the text i want to quote.', +'produces quote box' => 'produces a quote box like this:', + +'Code info' => 'When displaying source code you should make sure that you use the code tag. Text displayed with the code tag 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', + +'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 converts them to an image:' + +); diff --git a/lang/en/en_index.php b/lang/en/en_index.php new file mode 100644 index 0000000..92a07bc --- /dev/null +++ b/lang/en/en_index.php @@ -0,0 +1,29 @@ + 'Topics', +'Moderators' => 'Moderators', +'You' => 'You', +'can' => 'can', +'cannot' => 'cannot', +'post replies' => 'post replies to topics', +'post topics' => 'post new topics', +'edit posts' => 'edit your posts', +'delete posts' => 'delete your posts', +'delete topics' => 'delete your topics', +'This forum has' => 'This forum has', +'registered user' => 'registered user', +'registered users' => 'registered users', // plural +'topic' => 'topic', +'topics' => 'topics', // plural +'and' => 'and', +'post' => 'post', +'posts' => 'posts', // plural +'Newest user' => 'The newest registered user is', +'Currently serving' => 'Currently serving', +'guest' => 'guest', +'guests' => 'guests' // plural + +); diff --git a/lang/en/en_login.php b/lang/en/en_login.php new file mode 100644 index 0000000..7d4fad0 --- /dev/null +++ b/lang/en/en_login.php @@ -0,0 +1,28 @@ + 'Wrong username and/or password.', +'Forgotten pass' => 'Forgotten your password?', +'Login redirect' => 'Logged in successfully. Redirecting ...', +'Logout redirect' => 'Logged out. Redirecting ...', +'No e-mail match' => 'There is no user registered with the email address', +'Request pass' => 'Request password', +'Instructions' => 'Enter the e-mail address with which you registered. A new password together with a link to activate the new password will be sent to that address.', +'Password' => 'Password', +'Not registered' => 'Not registered yet?', + +// Forget password mail stuff +'Forget mail 1' => 'New password requested', +'Forget mail 2' => 'Hello', // as in "Hello someuser" +'Forget mail 3' => 'You have requested to have a new password assigned to your account in the discussion forum at', +'Forget mail 4' => '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 URL below will your password be changed.', +'Forget mail 5' => 'To change your password, please visit the URL below:', +'Forget mail 6' => 'When you have visited the above URL you can login with your new password:', +'Forget mail 7' => 'Do not reply to this message', +'Forget mail 8' => 'An email has been sent to', +'Forget mail 9' => 'with instructions on how to change your password. If it doesn\'t arrive you can contact the forum administrator at' + +); diff --git a/lang/en/en_misc.php b/lang/en/en_misc.php new file mode 100644 index 0000000..c7a5f2b --- /dev/null +++ b/lang/en/en_misc.php @@ -0,0 +1,17 @@ + 'All forums and posts have been marked as read. Redirecting ...', +'No reason' => 'You must enter a reason.', +'Report redirect' => 'Post reported. Redirecting ...', +'Report post' => 'Report post', +'Reason' => 'Reason', +'Reason desc' => 'Please enter a short reason why you are reporting this post.', +'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 ...' + +); diff --git a/lang/en/en_post.php b/lang/en/en_post.php new file mode 100644 index 0000000..69e491b --- /dev/null +++ b/lang/en/en_post.php @@ -0,0 +1,34 @@ + 'Topics must contain a subject.', +'Too long subject' => 'Subjects cannot be longer than 70 characters.', +'No caps subject' => 'Subjects must not contain only capital letters and special characters in this forum.', +'No message' => 'You must enter a message.', +'Too long message' => 'Posts cannot be longer that 65535 characters (64 Kb).', +'No caps message' => 'Messages must not contain only capital letters and special characters in this forum.', + +// Subscription mail stuff +'Reply mail 1' => 'Reply to topic', +'Reply mail 2' => 'replied to the topic', +'Reply mail 3' => 'to which you are subscribed.', +'Reply mail 4' => 'The post is located at', +'Reply mail 5' => 'You can unsubscribe by going to', +'Reply mail 6' => 'Do not reply to this message', + +// Miscellaneous +'Post redirect' => 'Post entered. Redirecting ...', +'Post a reply' => 'Post a reply', +'Post new topic' => 'Post new topic', +'wrote' => 'wrote', // For [quote]'s +'Show smilies' => 'Show smilies as icons', +'Subscribe' => 'Subscribe to this topic', +'Subject' => 'Subject', +'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.' + +); diff --git a/lang/en/en_prof_reg.php b/lang/en/en_prof_reg.php new file mode 100644 index 0000000..2afa6ca --- /dev/null +++ b/lang/en/en_prof_reg.php @@ -0,0 +1,32 @@ + 'Password', +'Timezone' => 'Timezone', +'Timezone info' => 'In order for the forum to display times correctly, you must select the timezone you are visiting from.', +'Hide e-mail' => 'Hide e-mail address from other users.', +'Hide e-mail info' => 'If you don\'t want other users to be able to see your e-mail address, you should make sure that this option is enabled. If you don\'t select it, users will be able to see your e-mail address in your profile and in your posts.', +'Save user/pass' => 'Save username and password between visits.', +'Save user/pass info' => 'This option sets whether the forum should "remember" you between visits. If enabled, you will not have to login every time you want to visit the forum. You will be logged in automatically. This feature uses cookies and thus, requires your browser to have cookies enabled. Recommended.', +'Re-enter pass' => 'Re-enter password to confirm.', + +'Username too short' => 'Usernames must be at least 2 characters long. Please choose another (longer) 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 BBCode' => 'Usernames may not contain any of the text formatting tags (BBCode) that the forum uses. Please choose another username.', +'Dupe username' => 'Someone else has already registered with that username. 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. Please go back and correct.', +'Banned e-mail' => 'The e-mail address you entered is banned in this forum. Please choose another e-mail address.', +'Dupe e-mail' => 'Someone else is already registered with that e-mail address. Please choose another e-mail address.', +'Sig too long' => 'Signatures cannot be longer than', +'characters' => 'characters', +'Sig too many lines' => 'Signatures cannot have more than', +'lines' => 'lines', +'Sig caps' => 'Signatures must not contain only capital letters and special characters. Please go back and correct.', +'Signature quote/code' => 'The quote and code BBCodes are not allowed in signatures. Please go back and correct.', +'Bad ICQ' => 'You entered an invalid ICQ UIN. Please go back and correct.' + +); diff --git a/lang/en/en_profile.php b/lang/en/en_profile.php new file mode 100644 index 0000000..5c122aa --- /dev/null +++ b/lang/en/en_profile.php @@ -0,0 +1,115 @@ + 'Profile', + +// 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', +'Old pass' => 'Old password', +'New pass' => 'New password', + +// E-mail stuff +'E-mail key bad' => 'The specified e-mail activation key was incorrect or has expired. Please re-request change of e-mail adress. If that fails, contact the forum administrator at', +'E-mail updated' => 'Your e-mail address has been updated.', +'Change mail 1' => 'Change e-mail address requested', +'Change mail 2' => 'Hello', // as in "Hello $username" +'Change mail 3' => 'You have requested to have a new e-mail address assigned to your account in the discussion forum at', +'Change mail 4' => 'Only if you visit the activation URL below will your e-mail address be changed. In order for the activation URL to work, you must be logged in to the forum.', +'Change mail 5' => 'To change your e-mail address, please visit the URL below:', +'Change mail 6' => 'Do not reply to this message', +'Change mail 7' => 'An email has been sent to', +'Change mail 8' => 'with instructions on how to activate the new e-mail address. If it doesn\'t arrive you can contact the forum administrator at', +'E-mail instructions' => 'Enter the new e-mail address and an e-mail will be sent to that address with an activation link. You must click the link in the e-mail you recieve to activate the new address.', +'Change e-mail' => 'Change e-mail address', +'New e-mail' => 'New e-mail', + +// 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 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' => 'The file you tried to upload is wider than the maximum allowed', +'Too high' => 'The file you tried to upload is 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 occured. Please try again.', +'Upload redirect' => 'Avatar uploaded. 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', +'File' => 'File', +'Upload' => 'Upload', // submit button + +// Form validation stuff +'Dupe username' => 'Someone else has already registered with that username. Please go back and try a different username.', +'Forbidden title' => 'The title you entered contains a forbidden word. You must choose a different title.', +'Profile redirect' => 'Profile updated. Redirecting ...', + +// Profile display stuff +'Not activated' => 'This user hasn\'t activated his/her account yet. The account is activated when he/she logs in the first time.', +'Not displayed' => 'Not displayed', +'No avatar' => 'No avatar', +'Show posts' => 'Show posts by this user', +'Realname' => 'Realname', +'Website' => 'Website', +'ICQ' => 'ICQ', +'AOL IM' => 'AOL IM', +'Yahoo' => 'Yahoo! Messenger', +'Location' => 'Location', +'Sig max length' => 'Max length', +'Sig max lines' => 'Max lines', +'Avatar' => 'Avatar', +'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. The checkbox \'Use avatar\' below must be checked in order for the avatar to be visible in your posts.', +'Change avatar' => 'Change avatar', +'Use avatar' => 'Use avatar.', +'Signature' => '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 favorite quote or your star sign. It\'s up to you! In your signature you can use embedded HTML or BBCode depending on the what is allowed in this particular forum. You can tell what features are allowed/enabled out in the left margin whenever you edit your signature.', +'Sig preview' => 'Current signature preview:', +'No sig' => 'No signature currently stored in profile.', +'Topics per page' => 'Topics per page', +'Topics per page info' => 'This setting controls how many topics are displayed per page when you view a forum. If you are uncertain about what to use, you can just leave it blank and the forum default will be used.', +'Posts per page' => 'Posts per page', +'Posts per page info' => 'This setting controls how many posts are displayed per page when you view a topic. If you are uncertain about what to use, you can just leave it blank and the forum default will be used.', +'Leave blank' => 'Leave blank to use forum default.', +'Use smilies' => 'Convert smilies to images by default.', +'Use smilies info' => 'If you enable this option, small images instead of text smilies will be displayed in your posts by default. You can still disable this by unchecking the checkbox on a post per post basis.', +'Show images' => 'Show images.', +'Show images info' => 'Disable this if you don\'t want to see images and icons in posts (this includes smilies and images displayed with the [img]-tag).', +'Show sigs' => 'Show user signatures.', +'Show sigs info' => 'Enable if you would like to see user signatures.', +'Open links new win' => 'Open links in new window.', +'Open links new win info' => 'This option sets whether you want links in posts to open new windows or not.', +'Style' => 'Style', +'Style info' => 'If you like you can use a different visual style for this forum.', +'Admin note' => 'Admin note', +'Instructions' => 'When you update your profile, you will be redirected back to this page.', + +// Administration stuff +'User admin' => 'User administration', +'Choose status' => 'Status', +'Choose status info' => 'Choose what status this user should have.', +'Update status' => 'Update status', +'Moderator in' => 'Moderator in', +'Moderator in info' => 'Choose what forums this user should be allowed to moderate. Note: This only applies to moderators.', +'Update forums' => 'Update forums', +'Delete user' => 'Delete user', +'Ban user' => 'Ban user', +'Confirm delete user' => 'Confirm delete user', +'Are you sure' => 'Are you sure that you want to delete this user?', +'Warning' => 'Warning! Deleted users cannot be restored.', +'OK' => ' OK ', // submit button (confirm user delete) +'User delete redirect' => 'User deleted. Redirecting ...', +'Update status redirect' => 'User status updated. Redirecting ...', +'Update forums redirect' => 'Forum moderator rights updated. Redirecting ...', +'Ban redirect' => 'Redirecting ...' + +); diff --git a/lang/en/en_register.php b/lang/en/en_register.php new file mode 100644 index 0000000..7990c90 --- /dev/null +++ b/lang/en/en_register.php @@ -0,0 +1,42 @@ + 'This forum is not accepting new registrations.', +'Reg cancel redirect' => 'Registration cancelled. Redirecting ...', +'Forum rules' => 'Forum rules', +'Accept' => 'Agree', +'Cancel' => 'Cancel', +'Register' => 'Register', + +// Form validation stuff (some of these are also used in post.php) +'Username censor' => 'The username you entered contained one or more censored words. Please choose another username.', +'Username dupe 1' => 'Someone else has 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 go back and try a different username.', +'E-mail not match' => 'E-mail addresses do not match. Please go back and correct.', + +// Registration e-mail stuff +'Reg e-mail 1' => 'Welcome!', +'Reg e-mail 2' => 'Thank you for registering at', +'Reg e-mail 3' => 'Your username is', +'Reg e-mail 4' => 'Your password is', +'Reg e-mail 5' => 'Login at', +'Reg e-mail 6' => 'to activate the account.', +'Reg e-mail 7' => 'Do not reply to this message', +'Reg e-mail 8' => 'Thank you for registering. Your password has been sent to', +'Reg e-mail 9' => 'If it doesn\'t arrive you can contact the forum administrator at', +'Reg complete' => 'Registration complete. Logging in and redirecting ...', + +// Register info +'Desc 1' => 'Registering is not required, but it 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 info' => 'Usernames can be between 2 and 25 characters long.', +'Pass info 1' => 'Passwords can be between 4 and 16 characters long. Passwords are case sensitive.', +'Pass info 2' => 'The forum will generate a random password that will be e-mailed to you as you register. You can then log in with this password and change it to whatever you like in your profile.', +'E-mail info 1' => 'You must enter a valid e-mail address as your password will be sent to that address (see above). You can choose to hide your e-mail address from other users (see below) to keep your privacy.', +'E-mail info 2' => 'Please enter a valid e-mail address. You can choose to hide your e-mail address from other users (see below) to keep your privacy.', +'Re-enter e-mail' => 'Re-enter e-mail address to confirm.', + +); diff --git a/lang/en/en_search.php b/lang/en/en_search.php new file mode 100644 index 0000000..ca6b23e --- /dev/null +++ b/lang/en/en_search.php @@ -0,0 +1,39 @@ + 'The administrator has disabled the search feature.', +'No guest search' => 'Guests are not allowed to use the search feature.', + +'Search' => 'Search', +'Keyword search' => 'Keywords', +'Keyword search info' => 'Enter a term or terms to search for. Separate terms with spaces. Use AND, OR and NOT to refine your search. Use the wildcard character * for partial matches.', +'Author search' => 'Author search', +'Author search info' => 'Enter the username of the author whose posts you wish to search for. Use wildcard character * for partial matches.', +'Search in' => 'Search in', +'Message and subject' => 'Message text and topic subject', +'Message only' => 'Message text only', +'Topic only' => 'Topic subject only', +'Forum search' => 'Forum', +'All forums' => 'All forums', +'Sort by' => 'Sort/group by', +'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', +'No terms' => 'You have to enter at least one keyword and/or an author to search for.', +'No hits' => 'Your search returned no hits.', +'Search results' => 'Search results', +'Topic/Message' => 'Topic/Message', +'User no posts' => 'There are no posts by this user in this forum.', +'Go to post' => 'Go to post', +'No new posts' => 'There are no topics with new posts since your last visit.', +'No unanswered' => 'There are no unanswered posts in this forum.' + +); diff --git a/lang/en/en_stopwords.txt b/lang/en/en_stopwords.txt new file mode 100644 index 0000000..f86c8cb --- /dev/null +++ b/lang/en/en_stopwords.txt @@ -0,0 +1,151 @@ +about +after +ago +all +almost +along +also +and +any +anybody +anywhere +are +arent +around +ask +bad +been +before +being +between +but +came +can +cant +come +could +couldnt +did +didnt +does +dont +each +either +else +even +every +everybody +everyone +find +for +from +get +going +gone +got +had +has +have +havent +having +her +here +hers +him +his +how +into +isnt +its +just +know +less +like +make +many +may +more +most +much +must +near +never +none +not +nothing +off +often +once +one +only +other +our +ours +out +over +please +rather +recent +said +see +she +should +small +some +something +sometime +somewhere +take +than +thank +thanks +that +the +their +theirs +them +then +there +these +they +thing +this +those +though +through +thus +too +true +two +under +until +upon +use +very +want +was +way +were +what +when +where +which +who +whom +whose +why +will +with +within +without +would +yes +yet +you +your +yours +lol +quote +code +img +wrote diff --git a/lang/en/en_topic.php b/lang/en/en_topic.php new file mode 100644 index 0000000..519b746 --- /dev/null +++ b/lang/en/en_topic.php @@ -0,0 +1,23 @@ + 'Post reply', +'Topic closed' => 'Topic closed', +'Moderated by' => 'Moderated by', +'From' => 'From', // User location +'Note' => 'Note', // Admin note +'Website' => 'Website', +'Guest' => 'Guest', +'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' + +); diff --git a/lang/en/en_userlist.php b/lang/en/en_userlist.php new file mode 100644 index 0000000..d76658f --- /dev/null +++ b/lang/en/en_userlist.php @@ -0,0 +1,12 @@ + 'User list', +'Other' => 'Other', +'All users' => 'All users', +'No users' => 'There are no registered users under', +'Not displayed' => 'Not displayed' + +); diff --git a/lang/en/index.html b/lang/en/index.html new file mode 100644 index 0000000..2db9a3c --- /dev/null +++ b/lang/en/index.html @@ -0,0 +1,8 @@ + + +. + + +. + + \ No newline at end of file diff --git a/lang/index.html b/lang/index.html new file mode 100644 index 0000000..2db9a3c --- /dev/null +++ b/lang/index.html @@ -0,0 +1,8 @@ + + +. + + +. + + \ No newline at end of file diff --git a/login.php b/login.php new file mode 100644 index 0000000..720dc85 --- /dev/null +++ b/login.php @@ -0,0 +1,219 @@ +query('SELECT id, username, password, save_pass, status FROM '.$db->prefix.'users WHERE username=\''.addslashes($username).'\'') or error('Unable to fetch user info', __FILE__, __LINE__, $db->error()); + list($user_id, $correct_username, $correct_password, $save_pass, $status) = $db->fetch_row($result); + + if ($correct_password == NULL || $correct_password != md5($password)) + message($lang_login['Wrong user/pass'].' '.$lang_login['Forgotten pass'].''); + + // Update the status if this is the first time the user logged in + if ($status == -1) + $db->query('UPDATE '.$db->prefix.'users SET status=0 WHERE id='.$user_id) or error('Unable to update user status', __FILE__, __LINE__, $db->error()); + + $expire = ($save_pass == '1') ? time() + 31536000 : 0; + + if (isset($_COOKIE['punbb_cookie'])) + { + list(, , $last_action, $last_timeout) = unserialize(un_escape($_COOKIE['punbb_cookie'])); + + setcookie('punbb_cookie', serialize(array($correct_username, $correct_password, $last_action, $last_timeout)), $expire, $cookie_path, $cookie_domain, $cookie_secure); + } + else + { + $now = time(); + + setcookie('punbb_cookie', serialize(array($correct_username, $correct_password, $now, $now)), $expire, $cookie_path, $cookie_domain, $cookie_secure); + } + + redirect($_POST['redirect_url'], $lang_login['Login redirect']); +} + + +else if ($action == 'out') +{ + if ($cookie['is_guest']) + header('Location: index.php'); + + // Remove user from "users online" list. + $db->query('DELETE FROM '.$db->prefix.'online WHERE ident=\''.addslashes($cookie['username']).'\'') or error('Unable to delete from online list', __FILE__, __LINE__, $db->error()); + + // Remove any left over search results + $db->query('DELETE FROM '.$db->prefix.'search_results WHERE ident=\''.addslashes($cookie['username']).'\'') or error('Unable to delete search results', __FILE__, __LINE__, $db->error()); + + list(, , $last_action, $last_timeout) = unserialize(un_escape($_COOKIE['punbb_cookie'])); + + setcookie('punbb_cookie', serialize(array('Guest', 'Guest', $last_action, $last_timeout)), time() + 31536000, $cookie_path, $cookie_domain, $cookie_secure); + + redirect('index.php', $lang_login['Logout redirect']); +} + + +else if ($action == 'forget' || $action == 'forget_2') +{ + if (isset($_POST['form_sent'])) + { + require 'include/email.php'; + + // Validate the email-address + $email = strtolower(trim($_POST['req_email'])); + if (!is_valid_email($email)) + message($lang_common['Invalid e-mail']); + + $result = $db->query('SELECT id, username FROM '.$db->prefix.'users WHERE email=\''.escape($email).'\'') or error('Unable to fetch user info', __FILE__, __LINE__, $db->error()); + + if ($db->num_rows($result)) + { + // Loop through users we found + while ($cur_hit = $db->fetch_assoc($result)) + { + $new_password = random_pass(8); + $new_password_key = random_pass(8); + + $db->query('UPDATE '.$db->prefix.'users SET activate_string=\''.md5($new_password).'\', activate_key=\''.$new_password_key.'\' WHERE id='.$cur_hit['id']) or error('Unable to update activation data', __FILE__, __LINE__, $db->error()); + + $mail_subject = $lang_login['Forget mail 1']; + $mail_message = $lang_login['Forget mail 2'].' '.$cur_hit['username'].','."\r\r\n\n".$lang_login['Forget mail 3'].' '.$options['base_url'].'/. '.$lang_login['Forget mail 4']."\r\r\n\n".$lang_login['Forget mail 5']."\r\n".$options['base_url'].'/profile.php?id='.$cur_hit['id'].'&action=change_pass&key='.$new_password_key."\r\r\n\n".$lang_login['Forget mail 6'].' '.$new_password."\r\r\n\n".'/Forum Mailer'."\r\n".'('.$lang_login['Forget mail 7'].')'; + $mail_extra = 'From: '.$options['board_title'].' Mailer <'.$options['webmaster_email'].'>'; + + pun_mail($email, $mail_subject, $mail_message, $mail_extra); + } + + message($lang_login['Forget mail 8'].' '.$email.' '.$lang_login['Forget mail 9'].' '.$options['admin_email'].'.'); + } + else + message($lang_login['No e-mail match'].' '.$email.'.'); + } + else + { + $page_title = htmlspecialchars($options['board_title']).' / '.$lang_login['Request pass']; + $validate_form = true; + $form_name = 'request_pass'; + $focus_element = 'req_email'; + require 'header.php'; + +?> +
 
+ + + + + + + + +
+ +
 
+ +
+ + + + + + + + + + + + + +
   
  
     

+
+ +
 
+ +
 
+ +
+ + "> + + + + + + + + + + + + + + + + +
   
   
   +
  

+  
+  

+
+
+ +
 
+query('SELECT topic_id FROM '.$db->prefix.'posts WHERE id='.$report) 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, 0); + + // 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 ($options['report_method'] == 0 || $options['report_method'] == 2) + $db->query('INSERT INTO '.$db->prefix.'reports (post_id, topic_id, forum_id, reported_by, created, message) VALUES('.$report.', '.$topic_id.', '.$forum_id.', '.$cur_user['id'].', '.time().', \''.escape($reason).'\')' ) or error('Unable to create report', __FILE__, __LINE__, $db->error()); + + // Should we e-mail the report? + if ($options['report_method'] == 1 || $options['report_method'] == 2) + { + // We send it to the complete mailing-list in one swoop + if ($options['mailing_list'] != '') + { + $mail_subject = 'Report('.$forum_id.') - '.$subject; + $mail_message = $cur_user['username'].' has reported the following message:'."\r\n".$options['base_url'].'/viewtopic.php?pid='.$report.'#'.$report."\r\n\r\n".'Reason:'."\r\n".$reason; + $mail_extra = 'From: '.$options['board_title'].' Mailer <'.$options['webmaster_email'].'>'; + + require 'include/email.php'; + pun_mail($options['mailing_list'], $mail_subject, $mail_message, $mail_extra); + } + } + + if ($_POST['redirect_url'] != '') + redirect($_POST['redirect_url'], $lang_misc['Report redirect']); + else + redirect('viewtopic.php?id='.$topic_id, $lang_misc['Report redirect']); + } + + + $page_title = htmlspecialchars($options['board_title']).' / '.$lang_misc['Report post']; + $validate_form = true; + $form_name = 'report'; + $focus_element = 'req_reason'; + $dimsubmit = true; + require 'header.php'; + +?> +
 
+ +
+ + "> + + + + + + + + + + + + +
   +

+   +
  
    

+
+ +
 
+query('SELECT subscribers FROM '.$db->prefix.'topics WHERE id='.$subscribe) or error('Unable to fetch topic subscribers', __FILE__, __LINE__, $db->error()); + if (!$db->num_rows($result)) + message($lang_common['Bad request']); + + $subscribers = $db->result($result, 0); + + if ($subscribers == '') + $subscribers = escape($cur_user['email']); + else + { + if (!strstr($subscribers, $cur_user['email'])) + $subscribers .= ','.$cur_user['email']; + else + message($lang_misc['Already subscribed']); + } + + $db->query('UPDATE '.$db->prefix.'topics SET subscribers=\''.$subscribers.'\' WHERE id='.$subscribe) or error('Unable to update topic subscribers', __FILE__, __LINE__, $db->error()); + + redirect('viewtopic.php?id='.$subscribe, $lang_misc['Subscribe redirect']); +} + + +else if (isset($_GET['unsubscribe'])) +{ + $unsubscribe = intval($_GET['unsubscribe']); + if (empty($unsubscribe)) + message($lang_common['Bad request']); + + if ($cookie['is_guest']) + message($lang_common['No permission']); + + $result = $db->query('SELECT subscribers FROM '.$db->prefix.'topics WHERE id='.$unsubscribe) or error('Unable to fetch topic subscribers', __FILE__, __LINE__, $db->error()); + if (!$db->num_rows($result)) + message($lang_common['Bad request']); + + $subscribers = $db->result($result, 0); + + if (strstr($subscribers, $cur_user['email'])) + { + $addresses = explode(',', $subscribers); + while (list($key, $value) = @each($addresses)) + { + if ($value == $cur_user['email']) + unset($addresses[$key]); + } + + if (count($addresses)) + { + $subscribers = implode(',', $addresses); + $db->query('UPDATE '.$db->prefix.'topics SET subscribers=\''.$subscribers.'\' WHERE id='.$unsubscribe) or error('Unable to update topic subscribers', __FILE__, __LINE__, $db->error()); + } + else + $db->query('UPDATE '.$db->prefix.'topics SET subscribers=NULL WHERE id='.$unsubscribe) or error('Unable to update topic subscribers', __FILE__, __LINE__, $db->error()); + + redirect('viewtopic.php?id='.$unsubscribe, $lang_misc['Unsubscribe redirect']); + } + else + message($lang_misc['Not subscribed']); +} +else + message($lang_common['Bad request']); diff --git a/moderate.php b/moderate.php new file mode 100644 index 0000000..a7cc352 --- /dev/null +++ b/moderate.php @@ -0,0 +1,261 @@ +query('SELECT poster_ip FROM '.$db->prefix.'posts WHERE id='.$get_host) or error('Unable to fetch post IP address', __FILE__, __LINE__, $db->error()); + $ip = $db->result($result, 0); + + message('The IP address is: '.$ip.'
The host name is: '.gethostbyaddr($ip).'

Show more users for this IP'); +} + + +// All other functions require forum-based moderator access +$fid = intval($_GET['fid']); +if (empty($fid)) + message($lang_common['Bad request']); + +if (!is_admmod($fid, $foo, $foo)) + message($lang_common['No permission']); + + +if (isset($_GET['move'])) +{ + if (isset($_POST['move_to'])) + { + confirm_referer('moderate.php'); + + $move = intval($_GET['move']); + $move_to_forum = intval($_POST['move_to_forum']); + if (empty($move) || empty($move_to_forum)) + message($lang_common['Bad request']); + + // Delete a redirect topic if there is one (only if we moved/copied the topic back to where it where it was once moved from) (start transaction) + $db->query('DELETE FROM '.$db->prefix.'topics WHERE forum_id='.$move_to_forum.' AND moved_to='.$move, PUN_TRANS_START) or error('Unable to delete redirect topic', __FILE__, __LINE__, $db->error()); + + // Move the topic + $db->query('UPDATE '.$db->prefix.'topics SET forum_id='.$move_to_forum.' WHERE id='.$move) or error('Unable to move topic', __FILE__, __LINE__, $db->error()); + + if ($_POST['with_redirect'] == '1') + { + // Fetch info for the redirect topic + $result = $db->query('SELECT poster, subject, posted, last_post FROM '.$db->prefix.'topics WHERE id='.$move) 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(\''.$moved_to['poster'].'\', \''.$moved_to['subject'].'\', '.$moved_to['posted'].', '.$moved_to['last_post'].', '.$move.', '.$fid.')') or error('Unable to create moved_to topic', __FILE__, __LINE__, $db->error()); + } + + update_forum($fid); // Update last_post in the forum FROM which the topic was moved/copied + update_forum($move_to_forum, PUN_TRANS_END); // Update last_post in the forum TO which the topic was moved/copied (end transaction) + + redirect('viewforum.php?id='.$move_to_forum, 'Topic moved/copied. Redirecting ...'); + } + else + { + $move = intval($_GET['move']); + if (empty($move)) + message($lang_common['Bad request']); + + $page_title = htmlspecialchars($options['board_title']).' / Moderate'; + require 'header.php'; + +?> +
 
+ +
+ + + + + + + +
Move topic
+
 Move to  

+  Move with redirect (leave a redirect topic)

+   

+
+
+ +
 
+query('UPDATE '.$db->prefix.'topics SET closed=\'1\' WHERE id='.$close) or error('Unable to close topic', __FILE__, __LINE__, $db->error()); + + redirect('viewtopic.php?id='.$close, 'Topic closed. Redirecting ...'); +} + + +else if (isset($_GET['open'])) +{ + confirm_referer('viewtopic.php'); + + $open = intval($_GET['open']); + if (empty($open)) + message($lang_common['Bad request']); + + $db->query('UPDATE '.$db->prefix.'topics SET closed=\'0\' WHERE id='.$open) or error('Unable to open topic', __FILE__, __LINE__, $db->error()); + + redirect('viewtopic.php?id='.$open, 'Topic opened. Redirecting ...'); +} + + +else if (isset($_GET['stick'])) +{ + confirm_referer('viewtopic.php'); + + $stick = intval($_GET['stick']); + if (empty($stick)) + message($lang_common['Bad request']); + + $db->query('UPDATE '.$db->prefix.'topics SET sticky=\'1\' WHERE id='.$stick) or error('Unable to stick topic', __FILE__, __LINE__, $db->error()); + + redirect('viewtopic.php?id='.$stick, 'Topic sticked. Redirecting ...'); +} + + +else if (isset($_GET['unstick'])) +{ + confirm_referer('viewtopic.php'); + + $unstick = intval($_GET['unstick']); + if (empty($unstick)) + message($lang_common['Bad request']); + + $db->query('UPDATE '.$db->prefix.'topics SET sticky=\'0\' WHERE id='.$unstick) or error('Unable to unstick topic', __FILE__, __LINE__, $db->error()); + + redirect('viewtopic.php?id='.$unstick, 'Topic sticked. Redirecting ...'); +} + + +else if (isset($_GET['edit_subscribers'])) +{ + $edit_subscribers = intval($_GET['edit_subscribers']); + if (empty($edit_subscribers)) + message($lang_common['Bad request']); + + if (isset($_POST['update'])) + { + confirm_referer('moderate.php'); + + $subscribers = strtolower(preg_replace("/[\s]+/", '', trim($_POST['subscribers']))); + $subscribers = ($subscribers != '') ? '\''.$subscribers.'\'' : 'NULL'; + + $db->query('UPDATE '.$db->prefix.'topics SET subscribers='.$subscribers.' WHERE id='.$edit_subscribers) or error('Unable to update topic subscribers', __FILE__, __LINE__, $db->error()); + + redirect('viewtopic.php?id='.$edit_subscribers, 'Subscribers updated. Redirecting ...'); + } + else + { + $page_title = htmlspecialchars($options['board_title']).' / Moderate'; + require 'header.php'; + +?> +
 
+ +
+ + + + +query('SELECT subscribers FROM '.$db->prefix.'topics WHERE id='.$edit_subscribers) or error('Unable to fetch topic subscribers', __FILE__, __LINE__, $db->error()); + $subscribers = $db->result($result, 0); + +?> + + + + + + + + +
Edit subscribers
Subscribers   + A comma-separated list of subscribed e-mail addresses.

+   +
Actions   +
 

+
+
+ +
 
+'.$lang_common['Login'].' '.$lang_common['or'].' '.$lang_common['register'].'.'); + + +// Load the post.php language file +require 'lang/'.$language.'/'.$language.'_post.php'; + +if (isset($_POST['form_sent'])) +{ + // Flood protection + if (isset($cur_user['status']) < 1 && isset($cur_user['last_post']) != '' && (time() - $cur_user['last_post']) < $options['flood_interval']) + message($lang_post['Flood start'].' '.$options['flood_interval'].' '.$lang_post['flood end']); + + // Make sure form_user is correct + if (($cookie['is_guest'] && $_POST['form_user'] != 'Guest') || (!$cookie['is_guest'] && $_POST['form_user'] != $cur_user['username'])) + message($lang_common['Bad request']); + + $smilies = $_POST['smilies']; + + // If it's a reply + if (isset($_GET['tid'])) + { + $tid = intval($_GET['tid']); + if (empty($tid)) + message($lang_common['Bad request']); + + if ($permissions['users_post'] == '0' && $cur_user['status'] < 1 || $permissions['guests_post'] == '0' && $cookie['is_guest']) + message($lang_common['No permission']); + + $result = $db->query('SELECT closed, forum_id FROM '.$db->prefix.'topics WHERE id='.$tid) or error('Unable to fetch post info', __FILE__, __LINE__, $db->error()); + if (!$db->num_rows($result)) + message($lang_common['Bad request']); + + list($closed, $forum_id) = $db->fetch_row($result); + + $forum_closed = '0'; + if (!is_admmod($forum_id, $forum_closed, $admmod_only)) + { + if ($admmod_only == '1' && $cur_user['status'] < 1 || $closed == '1' || $forum_closed == '1') + message($lang_common['No permission']); + } + } + // If it's a new topic + else if (isset($_GET['fid'])) + { + $fid = intval($_GET['fid']); + if (empty($fid)) + message($lang_common['Bad request']); + + if ($permissions['users_post_topic'] == '0' && $cur_user['status'] < 1 || $permissions['guests_post_topic'] == '0' && $cookie['is_guest']) + message($lang_common['No permission']); + + $result = $db->query('SELECT moderators, admmod_only, closed FROM '.$db->prefix.'forums WHERE id='.$fid) or error('Unable to fetch forum info', __FILE__, __LINE__, $db->error()); + if (!$db->num_rows($result)) + message($lang_common['Bad request']); + + list($moderators, $admmod_only, $forum_closed) = $db->fetch_row($result); + $mods_array = ($moderators != '') ? unserialize($moderators) : array(); + + if ($admmod_only == '1' && $cur_user['status'] < 1 || $forum_closed == '1' && $cur_user['status'] < 2 && !array_key_exists($cur_user['username'], $mods_array)) + message($lang_common['No permission']); + + $subject = trim(un_escape($_POST['req_subject'])); + if ($subject == '') + message($lang_post['No subject']); + else if (strlen($subject) > 70) + message($lang_post['Too long subject']); + else if ($permissions['subject_all_caps'] == '0' && !preg_match("/[[:lower:]]/", $subject) && $cur_user['status'] < 1) + message($lang_post['No caps subject']); + } + else + message($lang_common['Bad request']); + + + // If the user is logged in we get the username and e-mail from $cur_user + if (!$cookie['is_guest']) + { + $username = $cur_user['username']; + $email = $cur_user['email']; + } + // Otherwise it should be in $_POST + else + { + $username = trim(un_escape($_POST['req_username'])); + $email = trim($_POST['req_email']); + + // Load the register.php/profile.php language files + require 'lang/'.$language.'/'.$language.'_prof_reg.php'; + require 'lang/'.$language.'/'.$language.'_register.php'; + + // It's a guest, so we have to check the username + if (strlen($username) < 2) + message($lang_prof_reg['Username too short']); + else if (!strcasecmp($username, 'Guest') || !strcasecmp($username, $lang_common['Guest'])) + message($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)) + message($lang_prof_reg['Username IP']); + else if (preg_match('#\[b\]|\[/b\]|\[u\]|\[/u\]|\[i\]|\[/i\]|\[color|\[/color\]|\[quote\]|\[/quote\]|\[code\]|\[/code\]|\[img\]|\[/img\]|\[url|\[/url\]|\[email|\[/email\]#i', $username)) + message($lang_prof_reg['Username BBCode']); + + // Check username for any censored words + $temp = censor_words($username); + if (strcmp($temp, $username)) + message($lang_register['Username censor']); + + + // Check that the username (or a too similar username) is not already registered + $result = $db->query('SELECT username FROM '.$db->prefix.'users WHERE username=\''.addslashes($username).'\' OR username=\''.addslashes(preg_replace("/[^\w]/", '', $username)).'\'') or error('Unable to fetch user info', __FILE__, __LINE__, $db->error()); + + if ($db->num_rows($result)) + { + $busy = $db->result($result, 0); + message($lang_register['Username dupe 1'].' '.htmlspecialchars($busy).'. '.$lang_register['Username dupe 2']); + } + + + require 'include/email.php'; + + if (!is_valid_email($email)) + message($lang_common['Invalid e-mail']); + } + + $message = trim(un_escape($_POST['req_message'])); + + // Make sure all newlines are \n and not \r\n or \r + $message = str_replace("\r", "\n", str_replace("\r\n", "\n", $message)); + + if ($message == '') + message($lang_post['No message']); + else if (strlen($message) > 65535) + message($lang_post['Too long message']); + else if ($permissions['message_all_caps'] == '0' && !preg_match("/[[:lower:]]/", $message) && $cur_user['status'] < 1) + message($lang_post['No caps message']); + + + // Validate BBCode syntax + if ($permissions['message_bbcode'] == '1' && strpos($message, '[') !== false && strpos($message, ']') !== false) + { + // Change all BBCodes to lower case (this way a lot of regex searches can be case sensitive) + $a = array('[B]', '[I]', '[U]', '[/B]', '[/I]', '[/U]'); + $b = array('[b]', '[i]', '[u]', '[/b]', '[/i]', '[/u]'); + $message = str_replace($a, $b, $message); + + $a = array("#\[quote\]#i", "#\[/quote\]#i", "#\[code\]#i", "#\[/code\]#i", "#\[colou?r=([a-zA-Z]*|\#?[0-9a-fA-F]{6})\]#i", "#\[/colou?r\]#i", "#\[img\]#i", "#\[/img\]#i", "#\[email\]#i", "#\[email=#i", "#\[/email\]#i", "#\[url\]#i", "#\[url=#i", "#\[/url\]#i"); + $b = array('[quote]', '[/quote]', '[code]', '[/code]', "[color=\\1]", '[/color]', '[img]', '[/img]', '[email]', '[email=', '[/email]', '[url]', '[url=', '[/url]'); + $message = preg_replace($a, $b, $message); + + require 'include/parser.php'; + if ($overflow = check_tag_order($message)) + // The quote depth level was too high, so we strip out the inner most quote(s) + $message = substr($message, 0, $overflow[0]).substr($message, $overflow[1], (strlen($message) - $overflow[0])); + } + + + if ($smilies != '1') $smilies = '0'; + + $now = time(); + require 'include/searchidx.php'; + + // If it's a reply + if (isset($_GET['tid'])) + { + // Get the topic and any subscribed users + $result = $db->query('SELECT subject, subscribers FROM '.$db->prefix.'topics WHERE id='.$tid) or error('Unable to fetch topic info', __FILE__, __LINE__, $db->error()); + list($subject, $subscribers_save) = $db->fetch_row($result); + + if (!$cookie['is_guest']) + { + // Insert the new post (start transaction) + $db->query('INSERT INTO '.$db->prefix.'posts (poster, poster_id, poster_ip, message, smilies, posted, topic_id) VALUES(\''.addslashes($username).'\', '.$cur_user['id'].', \''.get_remote_address().'\', \''.addslashes($message).'\', \''.$smilies.'\', '.$now.', '.$tid.')', PUN_TRANS_START) or error('Unable to create post', __FILE__, __LINE__, $db->error()); + $new_pid = $db->insert_id(); + + if ($options['subscriptions'] == '1' && isset($_POST['subscribe']) == '1') + { + if ($subscribers_save == '') + $subscribers = $cur_user['email']; + else + { + if (!strstr($subscribers_save, $cur_user['email'])) + $subscribers = $subscribers_save.','.$cur_user['email']; + else + $subscribers = $subscribers_save; + } + + // Update topic + $db->query('UPDATE '.$db->prefix.'topics SET num_replies=num_replies+1, subscribers=\''.$subscribers.'\', last_post='.$now.', last_post_id='.$new_pid.', last_poster=\''.addslashes($username).'\' WHERE id='.$tid) or error('Unable to update topic', __FILE__, __LINE__, $db->error()); + } + else + // Update topic + $db->query('UPDATE '.$db->prefix.'topics SET num_replies=num_replies+1, last_post='.$now.', last_post_id='.$new_pid.', last_poster=\''.addslashes($username).'\' WHERE id='.$tid) or error('Unable to update topic', __FILE__, __LINE__, $db->error()); + } + else + { + // It's a guest. Insert the new post (start transaction) + $db->query('INSERT INTO '.$db->prefix.'posts (poster, poster_ip, poster_email, message, smilies, posted, topic_id) VALUES(\''.addslashes($username).'\', \''.get_remote_address().'\', \''.$email.'\', \''.addslashes($message).'\', \''.$smilies.'\', '.$now.', '.$tid.')', PUN_TRANS_START) or error('Unable to create post', __FILE__, __LINE__, $db->error()); + $new_pid = $db->insert_id(); + + // Update topic + $db->query('UPDATE '.$db->prefix.'topics SET num_replies=num_replies+1, last_post='.$now.', last_post_id='.$new_pid.', last_poster=\''.addslashes($username).'\' WHERE id='.$tid) or error('Unable to update topic', __FILE__, __LINE__, $db->error()); + } + + update_search_index('post', $new_pid, $message); + + update_forum($forum_id, PUN_TRANS_END); // end transaction + + // If there are any subscribed users and it's not the posting user him/herself + if ($subscribers_save != '' && $subscribers_save != isset($cur_user['email'])) + { + $addresses = explode(',', $subscribers_save); + $addresses = array_map('trim', $addresses); + + foreach ($addresses as $key => $value) + { + if ($value == isset($cur_user['email'])) + unset($addresses[$key]); // Remove the user who is posting (no need to e-mail him/her) + } + $subscribers_save = implode(',', $addresses); + + $mail_subject = $lang_post['Reply mail 1'].': '.$subject; + $mail_message = $username.' '.$lang_post['Reply mail 2'].' \''.$subject.'\' '.$lang_post['Reply mail 3']."\r\n\r\n".$lang_post['Reply mail 4'].' '.$options['base_url'].'/viewtopic.php?pid='.$new_pid.'#'.$new_pid."\r\n\r\n".$lang_post['Reply mail 5'].' '.$options['base_url'].'/misc.php?unsubscribe='.$tid."\r\n\r\n".'/Forum Mailer'."\r\n".'('.$lang_post['Reply mail 6'].')'; + $mail_extra = 'From: '.$options['board_title'].' Mailer <'.$options['webmaster_email'].'>'; + + require_once 'include/email.php'; // It could've been included once already + pun_mail($subscribers_save, $mail_subject, $mail_message, $mail_extra); + } + } + // If it's a new topic + else if (isset($_GET['fid'])) + { + if (!$cookie['is_guest']) + { + // Create the topic (start transaction) + if ($options['subscriptions'] == '1' && isset($_POST['subscribe']) == '1') + $db->query('INSERT INTO '.$db->prefix.'topics (poster, subject, posted, last_post, last_poster, subscribers, forum_id) VALUES(\''.addslashes($username).'\', \''.addslashes($subject).'\', '.$now.', '.$now.', \''.addslashes($username).'\', \''.$email.'\', '.$fid.')', PUN_TRANS_START) or error('Unable to create topic', __FILE__, __LINE__, $db->error()); + else + $db->query('INSERT INTO '.$db->prefix.'topics (poster, subject, posted, last_post, last_poster, forum_id) VALUES(\''.addslashes($username).'\', \''.addslashes($subject).'\', '.$now.', '.$now.', \''.addslashes($username).'\', '.$fid.')', PUN_TRANS_START) or error('Unable to create topic', __FILE__, __LINE__, $db->error()); + $new_tid = $db->insert_id(); + + // Create the post ("topic post") + $db->query('INSERT INTO '.$db->prefix.'posts (poster, poster_id, poster_ip, message, smilies, posted, topic_id) VALUES(\''.addslashes($username).'\', '.$cur_user['id'].', \''.get_remote_address().'\', \''.addslashes($message).'\', \''.$smilies.'\', '.$now.', '.$new_tid.')') or error('Unable to create post', __FILE__, __LINE__, $db->error()); + } + else + { + // Create the topic (start transaction) + $db->query('INSERT INTO '.$db->prefix.'topics (poster, subject, posted, last_post, last_poster, forum_id) VALUES(\''.addslashes($username).'\', \''.addslashes($subject).'\', '.$now.', '.$now.', \''.addslashes($username).'\', '.$fid.')', PUN_TRANS_START) or error('Unable to create topic', __FILE__, __LINE__, $db->error()); + $new_tid = $db->insert_id(); + + // Create the post ("topic post") + $db->query('INSERT INTO '.$db->prefix.'posts (poster, poster_ip, poster_email, message, smilies, posted, topic_id) VALUES(\''.addslashes($username).'\', \''.get_remote_address().'\', \''.$email.'\', \''.addslashes($message).'\', \''.$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.' 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, PUN_TRANS_END); // end transaction + } + + if (!$cookie['is_guest']) + $db->query('UPDATE '.$db->prefix.'users SET num_posts=num_posts+1, last_post='.$now.' WHERE id='.$cur_user['id']) or error('Unable to update user', __FILE__, __LINE__, $db->error()); + + redirect('viewtopic.php?pid='.$new_pid.'#'.$new_pid, $lang_post['Post redirect']); +} + + +else +{ + // If a topic id was specified in the url (it's a reply). + if (isset($_GET['tid'])) + { + $tid = intval($_GET['tid']); + if (empty($tid)) + message($lang_common['Bad request']); + + if ($permissions['users_post'] == '0' && $cur_user['status'] < 1 || $permissions['guests_post'] == '0' && $cookie['is_guest']) + message($lang_common['No permission']); + + $result = $db->query('SELECT subject, closed, forum_id FROM '.$db->prefix.'topics WHERE id='.$tid) or error('Unable to fetch topic info', __FILE__, __LINE__, $db->error()); + if (!$db->num_rows($result)) + message($lang_common['Bad request']); + + list($subject, $closed, $forum_id) = $db->fetch_row($result); + + $forum_closed = '0'; + if (!is_admmod($forum_id, $forum_closed, $admmod_only)) + { + if ($admmod_only == '1' && $cur_user['status'] < 1 || $closed == '1' || $forum_closed == '1') + message($lang_common['No permission']); + } + + $action = $lang_post['Post a reply']; + $form = '
'; + + // If a quoteid was specified in the url. + if (isset($_GET['qid'])) + { + $qid = intval($_GET['qid']); + if (empty($qid)) + message($lang_common['Bad request']); + + $result = $db->query('SELECT poster, message FROM '.$db->prefix.'posts WHERE id='.$qid) or error('Unable to fetch quote info', __FILE__, __LINE__, $db->error()); + if (!$db->num_rows($result)) + message($lang_common['Bad request']); + + list($qposter, $qmessage) = $db->fetch_row($result); + + if ($permissions['message_bbcode'] == '1') + $quote = '[quote][b][i]'.$qposter.' '.$lang_post['wrote'].':[/i][/b]'."\n\n".$qmessage."\n".'[/quote]'."\n"; + else + $quote = '> '.$qposter.' '.$lang_post['wrote'].':'."\n\n".'> '.$qmessage."\n"; + } + + // We have to fetch the forum name in order to display Title / Forum / Topic + $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 = ''.htmlspecialchars($db->result($result, 0)).''; + } + // If a forum_id was specified in the url (new topic). + else if (isset($_GET['fid'])) + { + $fid = intval($_GET['fid']); + if (empty($fid)) + message($lang_common['Bad request']); + + if ($permissions['users_post_topic'] == '0' && $cur_user['status'] < 1 || $permissions['guests_post_topic'] == '0' && $cookie['is_guest']) + message($lang_common['No permission']); + + $result = $db->query('SELECT forum_name, moderators, admmod_only, closed FROM '.$db->prefix.'forums WHERE id='.$fid) or error('Unable to fetch forum info', __FILE__, __LINE__, $db->error()); + if (!$db->num_rows($result)) + message($lang_common['Bad request']); + + list($forum_name, $moderators, $admmod_only, $forum_closed) = $db->fetch_row($result); + $mods_array = ($moderators != '') ? unserialize($moderators) : array(); + + if ($admmod_only == '1' && $cur_user['status'] < 1 || $forum_closed == '1' && $cur_user['status'] < 2 && !array_key_exists($cur_user['username'], $mods_array)) + message($lang_common['No permission']); + + $action = $lang_post['Post new topic']; + $form = ''; + + $forum = htmlspecialchars($forum_name); + } + else + message($lang_common['Bad request']); + + + $page_title = htmlspecialchars($options['board_title']).' / '.$action; + $validate_form = true; + $form_name = 'post'; + $dimsubmit = true; + + if (!$cookie['is_guest']) + { + if (isset($_GET['fid'])) + $focus_element = 'req_subject'; + else + $focus_element = 'req_message'; + } + else + $focus_element = 'req_username'; + + require 'header.php'; + + $cur_index = 1; + +?> + + + + +
/
+ + + + + + + + + + + + + + + + + + + + + + + + + '.$lang_post['Show smilies']; + else + $checkboxes[] = ' '.$lang_post['Show smilies']; + } + + if ($options['subscriptions'] == '1') + $checkboxes[] = ' '.$lang_post['Subscribe']; + + if (isset($checkboxes)) + $checkboxes = implode('
'."\n\t\t\t\t", $checkboxes)."\n"; + } + else if ($options['smilies'] == '1') + $checkboxes = ' '.$lang_post['Show smilies']."\n"; + + if (isset($checkboxes)) + { + +?> + + + + + + + + + +
   '; ?>
   
   
+   

+ HTML:   
+ BBCode:   
+ [img] tag:   
+ Smilies:    +
 
   + +
  
     

+
+ 0) + { + require 'include/parser.php'; + + $result = $db->query('SELECT poster, message, smilies, posted FROM '.$db->prefix.'posts WHERE topic_id='.$tid.' ORDER BY posted DESC LIMIT '.$options['topic_review']) or error('Unable to fetch topic review', __FILE__, __LINE__, $db->error()); + +?> + +
 
+ + + + + +fetch_assoc($result)) + { + $cur_post['message'] = parse_message($cur_post['message'], $cur_post['smilies']); + +?> + + + + +\n"; + } + +?> + +
 
+'.$lang_common['Login'].' '.$lang_common['or'].' '.$lang_common['register'].'.'); + + +$action = isset($_GET['action']); +$id = intval($_GET['id']); +if ($id < 2) + message($lang_common['Bad request']); + +// Load the profile.php/register.php language file +require 'lang/'.$language.'/'.$language.'_prof_reg.php'; + +// Load the profile.php language file +require 'lang/'.$language.'/'.$language.'_profile.php'; + + +if ($action == 'change_pass') +{ + if (isset($_GET['key'])) + { + // If the user is already logged in we shouldn't be here :) + if (!$cookie['is_guest']) + header('Location: index.php'); + + $key = $_GET['key']; + + $result = $db->query('SELECT activate_string, activate_key FROM '.$db->prefix.'users WHERE id='.$id) or error('Unable to fetch new password', __FILE__, __LINE__, $db->error()); + list($new_password, $new_password_key) = $db->fetch_row($result); + + if (strcmp($key, $new_password_key)) + message($lang_profile['Pass key bad'].' '.$options['admin_email'].'.'); + else + { + $db->query('UPDATE '.$db->prefix.'users SET password=\''.$new_password.'\', activate_string=NULL, activate_key=NULL WHERE id='.$id) or error('Unable to update password', __FILE__, __LINE__, $db->error()); + + message($lang_profile['Pass updated']); + } + } + + // Make sure we are allowed to change this users password + if ($cur_user['id'] != $id) + { + if ($cur_user['status'] < 1) // A regular user trying to change another users password? + message($lang_common['No permission']); + else if ($cur_user['status'] == 1) // A moderator trying to change an admin/mod's password? + { + $result = $db->query('SELECT status FROM '.$db->prefix.'users WHERE id='.$id) or error('Unable to fetch user info', __FILE__, __LINE__, $db->error()); + if (!$db->num_rows($result)) + message($lang_common['Bad request']); + else if ($db->result($result) > 0) + message($lang_common['No permission']); + } + } + + if (isset($_POST['form_sent'])) + { + $old_password = un_escape(isset($_POST['req_old_password'])); + $new_password1 = un_escape(isset($_POST['req_new_password1'])); + $new_password2 = un_escape(isset($_POST['req_new_password2'])); + + if (strlen($new_password1) < 4) + message($lang_prof_reg['Pass too short']); + if ($new_password1 != $new_password2) + message($lang_prof_reg['Pass not match']); + + $result = $db->query('SELECT password, save_pass FROM '.$db->prefix.'users WHERE id='.$id) or error('Unable to fetch password', __FILE__, __LINE__, $db->error()); + list($correct_password, $save_pass) = $db->fetch_row($result); + + if ($correct_password != NULL && !strcmp($correct_password, md5($old_password)) || $cur_user['status'] > 0) + { + $db->query('UPDATE '.$db->prefix.'users SET password=\''.md5($new_password1).'\' WHERE id='.$id) or error('Unable to update password', __FILE__, __LINE__, $db->error()); + + if ($cur_user['id'] == $id) + { + $expire = ($save_pass == '1') ? time() + 31536000 : 0; + + list(, , $last_action, $last_timeout) = unserialize(un_escape($_COOKIE['punbb_cookie'])); + + setcookie('punbb_cookie', serialize(array($cookie['username'], md5($new_password1), $last_action, $last_timeout)), $expire, $cookie_path, $cookie_domain, $cookie_secure); + } + + redirect('profile.php?id='.$id, $lang_profile['Pass updated redirect']); + } + else + message($lang_profile['Wrong pass']); + } + else + { + $page_title = htmlspecialchars($options['board_title']).' / '.$lang_profile['Profile']; + $validate_form = true; + $form_name = 'change_pass'; + $focus_element = ($cur_user['status'] < 1) ? 'req_old_password' : 'req_new_password1'; + + require 'header.php'; + +?> +
 
+ +
+ + + + + + + + + + + + + + + + + +
   
   +  
+     +
  
  

+
+ +
 
+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 (strcmp($key, $new_email_key)) + message($lang_profile['E-mail key bad'].' '.$options['admin_email'].'.'); + else + { + $db->query('UPDATE '.$db->prefix.'users SET email=\''.$new_email.'\', activate_string=NULL, activate_key=NULL WHERE id='.$id) or error('Unable to update e-mail address', __FILE__, __LINE__, $db->error()); + + message($lang_profile['E-mail updated']); + } + } + else if (isset($_POST['form_sent'])) + { + require '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 e-mail']); + + // Check it it's a banned e-mail address + if (is_banned_email($new_email)) + { + if ($permissions['allow_banned_email'] == '0') + message($lang_prof_reg['Banned e-mail']); + else if ($options['mailing_list'] != '') + { + $mail_subject = 'Alert - Banned e-mail detected'; + $mail_message = 'User "'.$cur_user['username'].'" changed to banned e-mail address: '.$new_email."\r\n\r\n".'User profile: '.$options['base_url'].'/profile.php?id='.$id; + $mail_extra = 'From: '.$options['board_title'].' Mailer <'.$options['webmaster_email'].'>'; + + require 'include/email.php'; + pun_mail($options['mailing_list'], $mail_subject, $mail_message, $mail_extra); + } + } + + // Check if someone else already has registered with that e-mail address + $result = $db->query('SELECT id, username FROM '.$db->prefix.'users WHERE email=\''.$new_email.'\'') or error('Unable to fetch user info', __FILE__, __LINE__, $db->error()); + $num_dupes = $db->num_rows($result); + + if ($num_dupes) // We found duplicate e-mail addresses + { + if ($permissions['allow_dupe_email'] == '0') + message($lang_prof_reg['Dupe e-mail']); + else if ($options['mailing_list'] != '') + { + while ($cur_dupe = $db->fetch_assoc($result)) + $dupe_list[] = $cur_dupe['username']; + + $mail_subject = 'Alert - Duplicate e-mail detected'; + $mail_message = 'User "'.$cur_user['username'].'" changed to an e-mail address that also belongs to: '.implode(', ', $dupe_list)."\r\n\r\n".'User profile: '.$options['base_url'].'/profile.php?id='.$id; + $mail_extra = 'From: '.$options['board_title'].' Mailer <'.$options['webmaster_email'].'>'; + + require 'include/email.php'; + pun_mail($options['mailing_list'], $mail_subject, $mail_message, $mail_extra); + } + } + + + $new_email_key = random_pass(8); + + $db->query('UPDATE '.$db->prefix.'users SET activate_string=\''.$new_email.'\', activate_key=\''.$new_email_key.'\' WHERE id='.$id) or error('Unable to update activation data', __FILE__, __LINE__, $db->error()); + + $mail_subject = $lang_profile['Change mail 1']; + $mail_message = $lang_profile['Change mail 2'].' '.$cur_user['username'].','."\r\n\r\n".$lang_profile['Change mail 3'].' '.$options['base_url'].'/. '.$lang_profile['Change mail 4']."\r\n\r\n".$lang_profile['Change mail 5']."\r\n".$options['base_url'].'/profile.php?action=change_email&id='.$id.'&key='.$new_email_key."\r\n\r\n".'/Forum Mailer'."\r\n".'('.$lang_profile['Change mail 6'].')'; + $mail_extra = 'From: '.$options['board_title'].' Mailer <'.$options['webmaster_email'].'>'; + + pun_mail($new_email, $mail_subject, $mail_message, $mail_extra); + + message($lang_profile['Change mail 7'].' '.$new_email.' '.$lang_profile['Change mail 8'].' '.$options['admin_email'].'.'); + } + else + { + $page_title = htmlspecialchars($options['board_title']).' / '.$lang_profile['Profile']; + $validate_form = true; + $form_name = 'change_email'; + $focus_element = 'req_new_email'; + + require 'header.php'; + +?> +
 
+ + + + + + + + +
+ +
 
+ +
+ + + + + + + + + + + + + +
   
  
  

+
+ +
 
+ $pun_config['o_avatars_width']) + { + message($lang_profile['Too wide'].' '.$pun_config['o_avatars_width'].' '.$lang_profile['pixels'].'.'); + } + if ($height > $pun_config['o_avatars_height']) + { + message($lang_profile['Too high'].' '.$pun_config['o_avatars_height'].' '.$lang_profile['pixels'].'.'); + } + if ($uploaded_file['size'] > $pun_config['o_avatars_size']) + { + message($lang_profile['Too large'].' '.$pun_config['o_avatars_size'].' '.$lang_profile['bytes'].'.'); + } + + if ($uploaded_file['type'] == 'image/gif') + { + $temp = @move_uploaded_file($uploaded_file['tmp_name'], $pun_config['o_avatars_dir'].'/'.$id.'.gif'); + @chmod($pun_config['o_avatars_dir'].'/'.$id.'.gif', 0644); + @unlink($pun_config['o_avatars_dir'].'/'.$id.'.jpg'); + @unlink($pun_config['o_avatars_dir'].'/'.$id.'.png'); + } + else if ($uploaded_file['type'] == 'image/jpeg' || $uploaded_file['type'] == 'image/pjpeg') + { + $temp = @move_uploaded_file($uploaded_file['tmp_name'], $pun_config['o_avatars_dir'].'/'.$id.'.jpg'); + @chmod($pun_config['o_avatars_dir'].'/'.$id.'.jpg', 0644); + @unlink($pun_config['o_avatars_dir'].'/'.$id.'.gif'); + @unlink($pun_config['o_avatars_dir'].'/'.$id.'.png'); + } + else if ($uploaded_file['type'] == 'image/png' || $uploaded_file['type'] == 'image/x-png') +{ + $temp = @move_uploaded_file($uploaded_file['tmp_name'], $pun_config['o_avatars_dir'].'/'.$id.'.png'); + @chmod($pun_config['o_avatars_dir'].'/'.$id.'.png', 0644); + @unlink($pun_config['o_avatars_dir'].'/'.$id.'.gif'); + @unlink($pun_config['o_avatars_dir'].'/'.$id.'.jpg'); + + if (!$temp) + message($lang_profile['Move failed'].' '.$pun_config['o_admin_email'].'.'); +} + +else { + message($lang_profile['Unknown failure']); +} + +// Enable use_avatar (seems sane since the user just uploaded an avatar) +$result = $db->query('UPDATE '.$db->prefix.'users SET use_avatar=1 WHERE id='.$id); +if (!$result) { + error('Unable to update avatar state', __FILE__, __LINE__, $db->error()); +} + +redirect('profile.php?id='.$id, $lang_profile['Avatar upload redirect']); +} +else { + $page_title = pun_htmlspecialchars($pun_config['o_board_title']).' / '.$lang_profile['Profile']; + $validate_form = true; + $element_names = array('req_file' => $lang_profile['File']); + $form_name = 'upload_avatar'; + $focus_element = 'req_file'; + require $pun_root.'header.php'; +} + +?> +
 
+ + + + + + + + +
KB).
+ +
 
+ +
+ + + + + + + + + + + + + + +
   
  
  

+
+ +
 
+query('UPDATE '.$db->prefix.'users SET status='.$_POST['status'].' WHERE id='.$id) or error('Unable to update status', __FILE__, __LINE__, $db->error()); + + redirect('profile.php?id='.$id, $lang_profile['Update status redirect']); +} + + +else if (isset($_POST['update_forums'])) +{ + if ($cur_user['status'] < 2) + message($lang_common['No permission']); + + confirm_referer('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, 0); + + $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; + ksort($cur_moderators); + + $db->query('UPDATE '.$db->prefix.'forums SET moderators=\''.addslashes(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)) ? '\''.addslashes(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?id='.$id, $lang_profile['Update forums redirect']); +} + + +else if (isset($_POST['ban'])) +{ + if ($cur_user['status'] < 1) + message($lang_common['No permission']); + + redirect('admin_bans.php?add_ban='.$id, $lang_profile['Ban redirect']); +} + + +else if (isset($_POST['delete']) || isset($_POST['comply'])) +{ + if ($cur_user['status'] < 2) + message($lang_common['No permission']); + + confirm_referer('profile.php'); + + if (isset($_POST['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 username, status FROM '.$db->prefix.'users WHERE id='.$id) or error('Unable to fetch user info', __FILE__, __LINE__, $db->error()); + list($username, $status) = $db->fetch_row($status); + + if ($status > 0) + { + $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)) ? '\''.addslashes(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 the user + $db->query('DELETE FROM '.$db->prefix.'users WHERE id='.$id) or error('Unable to delete user', __FILE__, __LINE__, $db->error()); + + // 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()); + + redirect('index.php', $lang_profile['User delete redirect']); + } + else + { + $page_title = htmlspecialchars($options['board_title']).' / '.$lang_profile['Profile']; + require 'header.php'; + +?> +
 
+ +
+ + + + + + + +
+
 

+  

+     

+
+
+ +
 
+ 0) + { + confirm_referer('profile.php'); + + $username = trim(un_escape($_POST['username'])); + $old_username = trim(un_escape($_POST['old_username'])); + + if (strlen($username) < 2) + message($lang_prof_reg['Username too short']); + else if (!strcasecmp($username, 'Guest') || !strcasecmp($username, $lang_common['Guest'])) + message($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)) + message($lang_prof_reg['Username IP']); + else if (preg_match('#\[b\]|\[/b\]|\[u\]|\[/u\]|\[i\]|\[/i\]|\[color|\[/color\]|\[quote\]|\[/quote\]|\[code\]|\[/code\]|\[img\]|\[/img\]|\[url|\[/url\]|\[email|\[/email\]#i', $username)) + message($lang_prof_reg['Username BBCode']); + + // Check that the username is not already registered + $result = $db->query('SELECT 1 FROM '.$db->prefix.'users WHERE username=\''.addslashes($username).'\' AND id!='.$id) or error('Unable to fetch user info', __FILE__, __LINE__, $db->error()); + if ($db->num_rows($result)) + message($lang_profile['Dupe username']); + } + + + // Make sure all newlines are \n and not \r\n or \r + $signature = str_replace("\r", "\n", str_replace("\r\n", "\n", trim(un_escape($_POST['signature'])))); + + // Validate signature + if (strlen($signature) > $permissions['sig_length']) + message($lang_prof_reg['Sig too long'].' '.$permissions['sig_length'].' '.$lang_prof_reg['characters'].'.'); + else if (substr_count($signature, "\n") > ($permissions['sig_lines']-1)) + message($lang_prof_reg['Sig too many lines'].' '.$permissions['sig_lines'].' '.$lang_prof_reg['lines'].'.'); + else if ($signature && $permissions['sig_all_caps'] == '0' && !ereg( "[[:lower:]]", $signature)) + message($lang_prof_reg['Sig caps']); + + if ($permissions['sig_bbcode'] == '1') + { + // Change all BBCodes to lower case (this way a lot of regex searches can be case sensitive) + $a = array('[B]', '[I]', '[U]', '[/B]', '[/I]', '[/U]'); + $b = array('[b]', '[i]', '[u]', '[/b]', '[/i]', '[/u]'); + $message = str_replace($a, $b, isset($message)); + + $a = array('#\[colou?r=([a-zA-Z]*|\#?[0-9a-fA-F]{6})\]#i', '#\[/colou?r\]#i', '#\[img\]#i', '#\[/img\]#i', '#\[email\]#i', '#\[email=#i', '#\[/email\]#i', '#\[url\]#i', '#\[url=#i', '#\[/url\]#i'); + $b = array('[color=\\1]', '[/color]', '[img]', '[/img]', '[email]', '[email=', '[/email]', '[url]', '[url=', '[/url]'); + $message = preg_replace($a, $b, isset($message)); + + if (preg_match('/\[quote\]|\[\/quote\]|\[code\]|\[\/code\]/i', $signature)) + message($lang_prof_reg['Signature quote/code']); + } + + + if ($options['regs_validate'] == '0' || $cur_user['status'] > 0) + { + require 'include/email.php'; + + // Validate the email-address + $email = strtolower(trim($_POST['req_email'])); + if (!is_valid_email($email)) + message($lang_common['Invalid e-mail']); + } + + + // Add http:// if the URL doesn't contain it already + if ($form['url'] != '' && !stristr($form['url'], 'http://')) + $form['url'] = 'http://'.$form['url']; + + // If the ICQ UIN contains anything other than digits it's invalid + if ($form['icq'] != '' && preg_match('/[^0-9]/', $form[icq])) + message($lang_prof_reg['Bad ICQ']); + + + if ($form['disp_topics'] != '' && intval($form['disp_topics']) < 3) $form['disp_topics'] = 3; + if ($form['disp_topics'] != '' && intval($form['disp_topics']) > 75) $form['disp_topics'] = 75; + if ($form['disp_posts'] != '' && intval($form['disp_posts']) < 3) $form['disp_posts'] = 3; + if ($form['disp_posts'] != '' && intval($form['disp_posts']) > 75) $form['disp_posts'] = 75; + + if (isset($form['use_avatar']) != '1') $form['use_avatar'] = '0'; + if (isset($form['hide_email']) != '1') $form['hide_email'] = '0'; + if ($form['save_pass'] != '1') $form['save_pass'] = '0'; + if ($form['smilies'] != '1') $form['smilies'] = '0'; + if ($form['show_img'] != '1') $form['show_img'] = '0'; + if ($form['show_sig'] != '1') $form['show_sig'] = '0'; + if ($form['link_to_new_win'] != '1') $form['link_to_new_win'] = '0'; + + + // Singlequotes around non-empty values and NULL for empty values + foreach ($form as $key => $input) + { + $value = ($input != '') ? '\''.escape($input).'\'' : 'NULL'; + + $temp[] = $key.'='.$value; + } + + + if ($cur_user['status'] < 1) + { + if ($permissions['users_set_title'] == '1') + { + $user_title = trim($_POST['title']); + + if ($user_title != '') + { + // A list of words that the title may not contain + // If $language == 'en', there will be some duplicates, but it's not the end of the world + $forbidden = array('Member', 'Moderator', 'Administrator', 'Banned', 'Guest', $lang_common['Member'], $lang_common['Moderator'], $lang_common['Administrator'], $lang_common['Banned'], $lang_common['Guest']); + + if (in_array($user_title, $forbidden)) + message($lang_profile['Forbidden title']); + } + + $user_title_sql = ($user_title != '') ? 'title=\''.escape($user_title).'\', ' : 'title=NULL, '; + } + + $email_sql = ($options['regs_validate'] == '0') ? 'email=\''.$email.'\', ' : ''; + + $db->query('UPDATE '.$db->prefix.'users SET '.$email_sql.$user_title_sql.'signature=\''.addslashes($signature).'\', '.implode(',', $temp).' WHERE id='.$id) or error('Unable to update profile', __FILE__, __LINE__, $db->error()); + } + else + { + $user_title = trim($_POST['title']); + $admin_note = trim($_POST['admin_note']); + + $user_title = ($user_title != '') ? '\''.escape($user_title).'\'' : 'NULL'; + $admin_note = ($admin_note != '') ? '\''.escape($admin_note).'\'' : 'NULL'; + + // We only allow administrators to update the post counter + $posts_sql = ($cur_user['status'] > 1) ? 'num_posts='.intval($_POST['num_posts']).', ' : ''; + + $db->query('UPDATE '.$db->prefix.'users SET username=\''.addslashes($username).'\', email=\''.$email.'\', title='.$user_title.', signature=\''.addslashes($signature).'\', '.implode(',', $temp).', '.$posts_sql.'admin_note='.$admin_note.' WHERE id='.$id) or error('Unable to update profile', __FILE__, __LINE__, $db->error()); + + // If we changed the username we have to alter "poster" and "last_poster" for any posts, topics and forums + if (strcmp($username, $old_username)) + { + $db->query('UPDATE '.$db->prefix.'posts SET poster=\''.addslashes($username).'\' WHERE poster_id='.$id) or error('Unable to update posts', __FILE__, __LINE__, $db->error()); + $db->query('UPDATE '.$db->prefix.'topics SET poster=\''.addslashes($username).'\' WHERE poster=\''.addslashes($old_username).'\'') or error('Unable to update topics', __FILE__, __LINE__, $db->error()); + $db->query('UPDATE '.$db->prefix.'topics SET last_poster=\''.addslashes($username).'\' WHERE last_poster=\''.addslashes($old_username).'\'') or error('Unable to update topics', __FILE__, __LINE__, $db->error()); + $db->query('UPDATE '.$db->prefix.'forums SET last_poster=\''.addslashes($username).'\' WHERE last_poster=\''.addslashes($old_username).'\'') or error('Unable to update forums', __FILE__, __LINE__, $db->error()); + } + } + + redirect('profile.php?id='.$id, $lang_profile['Profile redirect']); +} + + +else +{ + $result = $db->query('SELECT username, email, title, realname, url, icq, aim, yahoo, location, use_avatar, signature, disp_topics, disp_posts, hide_email, save_pass, smilies, show_img, show_sig, link_to_new_win, timezone, style, num_posts, status, last_post, registered, admin_note FROM '.$db->prefix.'users WHERE 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'] != NULL) + { + require 'include/parser.php'; + + $parsed_signature = parse_signature($user['signature']); + } + + // Are we viewing our someone elses profile? (and are we not an admin/moderator) + if (isset($cur_user['id']) != $id && isset($cur_user['status']) < 1) + { + if ($user['hide_email'] != '1') + $email_field = ''.$user['email'].''; + else + $email_field = $lang_profile['Not displayed']; + + $user_title_field = get_title($user); + + if ($user['url'] != '') + { + $user['url'] = htmlspecialchars($user['url']); + + if ($options['censoring'] == '1') + $user['url'] = censor_words($user['url']); + + if ($cur_user['link_to_new_win'] != '0') + $url = ''.$user['url'].''; + else + $url = ''.$user['url'].''; + } + + if ($options['avatars'] == '1') + { + if ($user['use_avatar'] == '1') + { + if ($img_size = @getimagesize($options['avatars_dir'].'/'.$id.'.gif')) + $avatar_field = ''; + else if ($img_size = @getimagesize($options['avatars_dir'].'/'.$id.'.jpg')) + $avatar_field = ''; + else if ($img_size = @getimagesize($options['avatars_dir'].'/'.$id.'.png')) + $avatar_field = ''; + } + else + $avatar_field = $lang_profile['No avatar']; + } + + + $page_title = htmlspecialchars($options['board_title']).' / '.$lang_profile['Profile']; + require 'header.php'; + +?> +
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0): ?> + + + + + + + + + + + +
+ + + + + +
+
   
   
   
   
   
   
   
   
   
   
   + + + + +
+ +
+
   
   
   
+ +
 
+ 0) + { + $username_field = ''; + $email_field = ''; + $user_title_field = '  '.isset($lang_prof_reg['Leave blank']); + } + else + { + $username_field = htmlspecialchars($user['username']); + + if ($options['regs_validate'] == '1') + $email_field = $user['email'].' - '.$lang_profile['Change e-mail'].''; + else + $email_field = ''; + + if ($permissions['users_set_title'] == '1') + $user_title_field = '  '.$lang_prof_reg['Leave blank']; + else + { + $user_title_field = get_title($user); + + if ($options['censoring'] == '1') + $user_title_field = censor_words($user_title_field); + } + } + + if ($img_size = @getimagesize($options['avatars_dir'].'/'.$id.'.gif')) + $avatar_field = '
 '.$lang_profile['Change avatar'].''; + else if ($img_size = @getimagesize($options['avatars_dir'].'/'.$id.'.jpg')) + $avatar_field = '
 '.$lang_profile['Change avatar'].''; + else if ($img_size = @getimagesize($options['avatars_dir'].'/'.$id.'.png')) + $avatar_field = '
 '.$lang_profile['Change avatar'].''; + else + $avatar_field = ''.$lang_profile['Upload avatar'].''; + + if ($cur_user['status'] < 2) + $posts_field = $user['num_posts']; + else + $posts_field = ''; + + if ($user['signature'] != '') + $preview = ' '.$lang_profile['Sig preview'].'
'."\n\t\t\t\t".' _______________________________________
'."\n\t\t\t\t".''."\n\t\t\t\t\t".''."\n\t\t\t\t\t\t".''."\n\t\t\t\t\t".''."\n\t\t\t\t".'
'.$parsed_signature.'

'."\n"; + else + $preview = ' '.$lang_profile['Sig preview'].'
'."\n\t\t\t\t".' _______________________________________
'."\n\t\t\t\t".' '.$lang_profile['No sig'].'

'."\n"; + +?> +
 
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0): ?> + + + + 0): ?> + + + + + + + +
+ + + + + +
+
   
   
   
   
   
   
   
   
   
   
   +

+  

+ +
+   

+ HTML:   
+ BBCode:   
+ [img] tag:   
+ Smilies:   
+ :   
+ :    +
+

+  

+ +
     
     
   +

+   +
   +
+

+
+

+
+

+
+

+
+

+
+ +
   +

+   +
   
   
   
   
   +
  

+  

+
+
+ 0) + { + +?> + +
 
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
   +
  

+
   +

+    +   

+
   +


+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'.$extra.' ORDER BY c.position, c.id, f.position') or error('Unable to fetch category/forum list', __FILE__, __LINE__, $db->error()); + + while ($cur_forum = $db->fetch_assoc($result)) + { + if ($cur_forum['cid'] != $cur_category) // A new category since last iteration? + { + echo "\t\t\t\t".$cur_forum['cat_name'].'
'; + $cur_category = $cur_forum['cid']; + } + + $moderators = ($cur_forum['moderators'] != '') ? unserialize($cur_forum['moderators']) : array(); + + print "\t\t\t\t".' '.htmlspecialchars($cur_forum['forum_name']).'
'."\n"; + } + +?> +
+
  

+
   +
    

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


  

+
+
+ +
 
+query('SELECT username FROM '.$db->prefix.'users WHERE username=\''.addslashes($username).'\' OR username=\''.addslashes(preg_replace("/[^\w]/", '', $username)).'\'') or error('Unable to fetch user info', __FILE__, __LINE__, $db->error()); + + if ($db->num_rows($result)) + { + $busy = $db->result($result, 0); + message($lang_register['Username dupe 1'].' '.htmlspecialchars($busy).'. '.$lang_register['Username dupe 2']); + } + + + // Validate e-mail + require 'include/email.php'; + + if (!is_valid_email($email1)) + message($lang_common['Invalid e-mail']); + else if ($options['regs_validate'] == '1' && $email1 != $email2) + message($lang_register['E-mail not match']); + + // Check it it's a banned e-mail address + if (is_banned_email($email1)) + { + if ($permissions['allow_banned_email'] == '0') + message($lang_prof_reg['Banned e-mail']); + + $banned_email = true; // Used later when we send an alert e-mail + } + + // Check if someone else already has registered with that e-mail address + $result = $db->query('SELECT id, username FROM '.$db->prefix.'users WHERE email=\''.$email1.'\'') or error('Unable to fetch user info', __FILE__, __LINE__, $db->error()); + $num_dupes = $db->num_rows($result); + + if ($num_dupes > 0 && $permissions['allow_dupe_email'] == '0') + message($lang_prof_reg['Dupe e-mail']); + + + $hide_email = (isset($_POST['hide_email']) != '1') ? '0' : '1'; + $save_pass = (isset($_POST['save_pass']) != '1') ? '0' : '1'; + + // Insert the new user into the database. We have to do this now to get the last inserted id in order to + // send out an add an alert e-mail with a link to the users profile (phew!) + $now = time(); + + $intial_status = ($options['regs_validate'] == '0') ? 0 : -1; + + // Add the user + $db->query('INSERT INTO '.$db->prefix.'users (username, password, email, hide_email, save_pass, timezone, style, status, registered) VALUES(\''.addslashes($username).'\', \''.md5($password1).'\', \''.$email1.'\', '.$hide_email.', '.$save_pass.', '.$_POST['timezone'].' ,\''.$options['default_style'].'\' ,'.$intial_status.', '.$now.')') or error('Unable to create user', __FILE__, __LINE__, $db->error()); + $new_uid = $db->insert_id(); + + + // If we previously found out that the e-mail was banned + if (isset($banned_email) && $options['mailing_list'] != '') + { + $mail_subject = 'Alert - Banned e-mail detected'; + $mail_message = 'User "'.$username.'" registered with banned e-mail address: '.$email1."\r\n\r\n".'User profile: '.$options['base_url'].'/profile.php?id='.$new_uid; + $mail_extra = 'From: '.$options['board_title'].' Mailer <'.$options['webmaster_email'].'>'; + + require 'include/email.php'; + pun_mail($options['mailing_list'], $mail_subject, $mail_message, $mail_extra); + } + + // If we previously found out that the e-mail was a dupe + if ($num_dupes && $options['mailing_list'] != '') + { + while ($cur_dupe = $db->fetch_assoc($result)) + $dupe_list[] = $cur_dupe['username']; + + $mail_subject = 'Alert - Duplicate e-mail detected'; + $mail_message = 'User "'.$username.'" registered with an e-mail address that also belongs to: '.implode(', ', $dupe_list)."\r\n\r\n".'User profile: '.$options['base_url'].'/profile.php?id='.$new_uid; + $mail_extra = 'From: '.$options['board_title'].' Mailer <'.$options['webmaster_email'].'>'; + + require_once 'include/email.php'; + pun_mail($options['mailing_list'], $mail_subject, $mail_message, $mail_extra); + } + + + // Must the user validate the registration or do we log him/her in right now? + if ($options['regs_validate'] == '1') + { + $mail_subject = $lang_register['Reg e-mail 1']; + $mail_message = $lang_register['Reg e-mail 2'].' '.$options['base_url'].'/'."\r\n\r\n".$lang_register['Reg e-mail 3'].': '.$username."\r\n".$lang_register['Reg e-mail 4'].': '.$password1."\r\n\r\n".$lang_register['Reg e-mail 5'].' '.$options['base_url'].'/login.php '.$lang_register['Reg e-mail 6']."\r\n\r\n".'/Forum Mailer'."\r\n".'('.$lang_register['Reg e-mail 7'].')'; + $mail_extra = 'From: '.$options['board_title'].' Mailer <'.$options['webmaster_email'].'>'; + + pun_mail($email1, $mail_subject, $mail_message, $mail_extra); + + message($lang_register['Reg e-mail 8'].' '.$email1.'. '.$lang_register['Reg e-mail 9'].' '.$options['admin_email'].'.', true); + } + else + { + $expire = ($save_pass != '0') ? $now + 31536000 : 0; + + setcookie('punbb_cookie', serialize(array($username, md5($password1), $now, $now, $now)), $expire, $cookie_path, $cookie_domain, $cookie_secure); + } + + redirect('index.php', $lang_register['Reg complete']); +} + + +else +{ + $page_title = htmlspecialchars($options['board_title']).' / '.$lang_register['Register']; + $validate_form = true; + $form_name = 'register'; + $focus_element = 'req_username'; + require 'header.php'; + +?> +
 
+ + + + + + + + +
+

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

+   +
   +'.$lang_register['Pass info 2'].''."\n"; + else + { + +?> +

+  
+     + +
   +'.$lang_register['E-mail info 1'].'
'."\n\t\t\t\t".' 
'."\n\n\t\t\t\t".'   '.$lang_register['Re-enter e-mail']; + else + print "\t\t\t\t".'
'.$lang_register['E-mail info 2'].'

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

+   +
   +
+  

+
+   +
  
     

+
+ +
 
+'.$lang_common['Login'].' '.$lang_common['or'].' '.$lang_common['register'].'.'); + else if ($permissions['guests_search'] == '0') + message($lang_search['No guest search']); + + $disp_topics = $options['disp_topics_default']; + $disp_posts = $options['disp_posts_default']; +} + + +// Figure out what to do :-) +if (isset($_POST['action']) || isset($_GET['action']) || isset($_GET['search_id'])) +{ + $action = (isset($_POST['action'])) ? $_POST['action'] : ((isset($_GET['action'])) ? $_GET['action'] : null); + $forum = (isset($_POST['forum'])) ? intval($_POST['forum']) : -1; + $sort_dir = (isset($_POST['sort_dir'])) ? (($_POST['sort_dir'] == 'DESC') ? 'DESC' : 'ASC') : 'DESC'; + + // If a search_id was supplied + if (isset($_GET['search_id'])) + { + $search_id = intval($_GET['search_id']); + if (empty($search_id) || $search_id < 0) + message($lang_common['Bad request']); + } + // If it's a regular search (keywords and/or author) + else if ($action == 'search') + { + $keywords = (isset($_POST['keywords'])) ? trim($_POST['keywords']) : ((isset($_GET['keywords'])) ? trim($_GET['keywords']) : null); + $author = (isset($_POST['author'])) ? trim($_POST['author']) : ((isset($_GET['author'])) ? trim($_GET['author']) : null); + + if ((!$keywords && !$author)) + message($lang_search['No terms']); + + if ($author) + $author = str_replace('*', '%', $author); + + $show_as = (isset($_POST['show_as'])) ? $_POST['show_as'] : ((isset($_GET['show_as'])) ? $_GET['show_as'] : 'posts'); + $sort_by = (isset($_POST['sort_by'])) ? intval($_POST['sort_by']) : null; + $search_in = (!isset($_POST['search_in']) || $_POST['search_in'] == 'all') ? 0 : (($_POST['search_in'] == 'message') ? 1 : -1); + } + // If it's a user search (by id) + else if ($action == 'show_user') + { + $user_id = intval($_GET['user_id']); + if ($user_id < 2) + message($lang_common['Bad request']); + } + else + { + if ($action != 'show_new' && $action != 'show_unanswered') + message($lang_common['Bad request']); + } + + + // Fetch the list of forums + $result = $db->query('SELECT id, forum_name, admmod_only FROM '.$db->prefix.'forums') or error('Unable to fetch forum list', __FILE__, __LINE__, $db->error()); + $num_forums = $db->num_rows($result); + + // Build two arrays with foruminfo + $admmod_forums = array(); + for ($i = 0; $i < $num_forums; $i++) + { + $forum_list[$i] = $db->fetch_row($result); + if ($forum_list[$i][2] == '1') + $admmod_forums[$i] = $forum_list[$i][0]; // $admmod_forums contains the ID's of admin/mod only forums + } + + + // If a valid search_id was supplied we attempt to fetch the search results from the db + if (isset($search_id)) + { + if ($cookie['is_guest']) + $ident = get_remote_address(); + else + $ident = addslashes($cookie['username']); + + $result = $db->query('SELECT search_data FROM '.$db->prefix.'search_results WHERE id='.$search_id.' AND ident=\''.$ident.'\'') or error('Unable to fetch search results', __FILE__, __LINE__, $db->error()); + if ($row = $db->fetch_assoc($result)) + { + $temp = unserialize($row['search_data']); + + $search_results = $temp['search_results']; + $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? + if ($forum != -1) + { + if (in_array($forum, $admmod_forums) && $cur_user['status'] < 1) + message($lang_search['No hits']); + + $forum_sql = 't.forum_id = '.$forum; + } + else + { + if (empty($admmod_forums) || $cur_user['status'] > 0) + $forum_sql = ''; + else + $forum_sql = 't.forum_id NOT IN('.implode(',', $admmod_forums).')'; + } + + + if (isset($author) || isset($keywords)) + { + // If it's a search for keywords + if ($keywords) + { + $stopwords = @file('lang/'.$language.'/'.$language.'_stopwords.txt'); + $keywords = ' '.strtolower($keywords).' '; + + // Locate some common search operators + $operator_match = array('+', '-', '&&', '||'); + $operator_replace = array(' and ', ' not ', ' and ', ' or '); + $keywords = str_replace($operator_match, $operator_replace, $keywords); + + // Filter out non-alphabetical chars + $noise_match = array('^', '$', '&', '(', ')', '<', '>', '`', '\'', '"', '|', ',', '@', '_', '?', '%', '~', '.', '[', ']', '{', '}', ':', '\\', '/', '=', '#', '\'', ';', '!', '�'); + $noise_replace = array(' ', ' ', ' ', ' ', ' ', ' ', ' ', '', '', ' ', ' ', ' ', ' ', '', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '' , ' ', ' ', ' ', ' ', ' ', ' ', ' '); + $keywords = str_replace($noise_match, $noise_replace, $keywords); + + // Filter out stopwords + if (!empty($stopwords)) + { + foreach ($stopwords as $word) + { + $word = trim($word); + if ($word != 'and' || $word != 'or' || $word != 'not') + $text = preg_replace('#\b'.preg_quote($word).'\b#', ' ', isset($text)); + } + } + + // Split up keywords + $keywords_array = preg_split('#[\s]+#', substr($keywords, 1, -1)); + + + // Should we search in message body or topic subject specifically? + if ($search_in) + $search_in_cond = ($search_in > 0) ? 'AND m.subject_match = 0' : 'AND m.subject_match = 1'; + + $match_type = 'or'; + foreach ($keywords_array as $cur_word) + { + switch ($cur_word) + { + case 'and': + case 'or': + case 'not': + $match_type = $cur_word; + break; + + default: + { + $match_word = str_replace('*', '%', $cur_word); + + $sql = 'SELECT m.post_id FROM '.$db->prefix.'search_words AS w INNER JOIN '.$db->prefix.'search_matches AS m ON m.word_id = w.id WHERE w.word LIKE \''.$match_word.'\''.isset($search_in_cond); + + $result = $db->query($sql) or error('Unable to search for posts', __FILE__, __LINE__, $db->error()); + + $row = array(); + $result_list = null; + while ($temp = $db->fetch_row($result)) + { + $row[$temp[0]] = 1; + + if (!isset($word_count)) + $result_list[$temp[0]] = 1; + else if ( $match_type == 'or') + $result_list[$temp[0]] = 1; + else if ( $match_type == 'not') + $result_list[$temp[0]] = 0; + } + + if ($match_type === 'and' && $word_count > 0) { + foreach ($result_list as $post_id => $value) { + if (empty($row[$post_id])) { + $result_list[$post_id] = 0; + } + } +} + + $word_count = 0; + $word_count++; + $db->free_result($result); + + break; + } + } + } + + if ($result_list !== null) { + @reset($result_list); + foreach ($result_list as $post_id => $matches) { + if ($matches) { + $keyword_results[] = $post_id; + } + } + unset($result_list); +} +} + + // If it's a search for author name (and that author name isn't Guest) + if ($author && strcasecmp($author, 'Guest') && strcasecmp($author, $lang_common['Guest'])) + { + switch ($db_type) + { + case 'mysql': + $result = $db->query('SELECT id FROM '.$db->prefix.'users WHERE username LIKE \''.escape($author).'\'') or error('Unable to fetch users', __FILE__, __LINE__, $db->error()); + break; + + case 'pgsql': + $result = $db->query('SELECT id FROM '.$db->prefix.'users WHERE username ILIKE \''.escape($author).'\'') or error('Unable to fetch users', __FILE__, __LINE__, $db->error()); + break; + } + + if ($db->num_rows($result)) + { + while ($row = $db->fetch_row($result)) + $user_ids .= ( ($user_ids != '') ? ',' : '').$row[0]; + + $result = $db->query('SELECT id FROM '.$db->prefix.'posts WHERE poster_id IN('.$user_ids.')') or error('Unable to fetch matched posts list', __FILE__, __LINE__, $db->error()); + + $search_ids = array(); + while ($row = $db->fetch_row($result)) + $author_results[] = $row[0]; + + $db->free_result($result); + } + } + + + if ($author && $keywords) + { + // If we searched for both keywords and author name we want the intersection between the results + $search_ids = array_intersect($keyword_results, $author_results); + unset($keyword_results, $author_results); + } + else if ($keywords) + $search_ids = $keyword_results; + else + $search_ids = $author_results; + + $num_hits = count($search_ids); + if (!$num_hits) + message($lang_search['No hits']); + + + if ($show_as == 'topics') + { + if ($forum_sql == '') + $sql = 'SELECT topic_id FROM '.$db->prefix.'posts WHERE id IN('.implode(',', $search_ids).') GROUP BY topic_id'; + else + $sql = 'SELECT p.topic_id FROM '.$db->prefix.'posts AS p INNER JOIN '.$db->prefix.'topics AS t ON p.topic_id=t.id WHERE p.id IN('.implode(',', $search_ids).') AND '.$forum_sql.' GROUP BY p.topic_id'; + + $result = $db->query($sql) or error('Unable to fetch topic list', __FILE__, __LINE__, $db->error()); + + $search_ids = array(); + while ($row = $db->fetch_row($result)) + $search_ids[] = $row[0]; + + $db->free_result($result); + + $num_hits = count($search_ids); + } + else if ($forum_sql) + { + $sql = 'SELECT p.id FROM '.$db->prefix.'posts AS p INNER JOIN '.$db->prefix.'topics AS t ON p.topic_id=t.id WHERE p.id IN('.implode(',', $search_ids).') AND '.$forum_sql; + + $result = $db->query($sql) or error('Unable to fetch post list', __FILE__, __LINE__, $db->error()); + + $search_ids = array(); + while ($row = $db->fetch_row($result)) + $search_ids[] = $row[0]; + + $db->free_result($result); + + $num_hits = count($search_ids); + } + } + else if ($action == 'show_new' || $action == 'show_user' || $action == 'show_unanswered') + { + // If it's a search for new posts + if ($action == 'show_new') + { + if ($cookie['is_guest']) + message($lang_common['No permission']); + + if ($forum_sql != '') + $sql = 'SELECT t.id FROM '.$db->prefix.'topics AS t WHERE t.last_post>'.$cookie['last_timeout'].' AND '.$forum_sql; + else + $sql = 'SELECT id FROM '.$db->prefix.'topics WHERE last_post>'.$cookie['last_timeout']; + + $result = $db->query($sql) 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 posts by a specific user ID + else if ($action == 'show_user') + { + if ($forum_sql != '') + $sql = 'SELECT t.id FROM '.$db->prefix.'topics AS t INNER JOIN '.$db->prefix.'posts AS p ON p.topic_id=t.id WHERE p.poster_id='.$user_id.' AND '.$forum_sql.' GROUP BY t.id'; + else + $sql = 'SELECT t.id FROM '.$db->prefix.'topics AS t INNER JOIN '.$db->prefix.'posts AS p ON p.topic_id=t.id WHERE p.poster_id='.$user_id.' GROUP BY t.id'; + + $result = $db->query($sql) or error('Unable to fetch topic list', __FILE__, __LINE__, $db->error()); + $num_hits = $db->num_rows($result); + + if (!$num_hits) + message($lang_search['User no posts']); + } + // If it's a search for unanswered posts + else + { + if ($forum_sql != '') + $sql = 'SELECT t.id FROM '.$db->prefix.'topics AS t WHERE t.num_replies=0 AND t.moved_to IS NULL AND '.$forum_sql; + else + $sql = 'SELECT id FROM '.$db->prefix.'topics WHERE num_replies=0 AND moved_to IS NULL'; + + $result = $db->query($sql) 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; + + $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 + $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) > 0) + { + while ($row = $db->fetch_row($result)) + $old_searches[] = '\''.$row[0].'\''; + + $db->query('DELETE FROM '.$db->prefix.'search_results WHERE ident NOT IN('.implode(',', $old_searches).')') or error('Unable to delete search results', __FILE__, __LINE__, $db->error()); + } + + // Final search results + $search_results = implode(',', $search_ids); + + // Fill an array with our results and search properties + $temp['search_results'] = $search_results; + $temp['num_hits'] = $num_hits; + $temp['sort_by'] = $sort_by; + $temp['sort_dir'] = $sort_dir; + $temp['show_as'] = $show_as; + $temp = addslashes(serialize($temp)); + $search_id = mt_rand(); + + if ($cookie['is_guest']) + $ident = get_remote_address(); + else + $ident = addslashes($cookie['username']); + + $db->query('UPDATE '.$db->prefix.'search_results SET id='.$search_id.', search_data=\''.$temp.'\' WHERE ident=\''.$ident.'\'') or error('Unable to update search results', __FILE__, __LINE__, $db->error()); + if (!$db->affected_rows()) + $db->query('INSERT INTO '.$db->prefix.'search_results (id, ident, search_data) VALUES('.$search_id.', \''.$ident.'\', \''.$temp.'\')') or error('Unable to insert search results', __FILE__, __LINE__, $db->error()); + } + + // Fetch results to display + if ($search_results != '') + { + switch ($sort_by) + { + case 1: + $sql = ($show_as == 'topics') ? 't.poster' : 'p.poster'; + break; + + case 2: + $sql = 't.subject'; + break; + + case 3: + $sql = 't.forum_id'; + break; + + case 4: + $sql = 't.last_post'; + break; + + default: + { + $sql = ($show_as == 'topics') ? 't.posted' : 'p.posted'; + + if ($show_as == 'topics') + $group_by = ', t.posted'; + + break; + } + } + $group_by = ''; + if ($show_as == 'posts') + $sql = 'SELECT p.id AS pid, p.poster AS pposter, p.poster_id, SUBSTRING(p.message, 1, 140) AS message, t.id AS tid, t.poster, t.subject, t.last_post, t.last_post_id, t.last_poster, t.num_replies, t.forum_id FROM '.$db->prefix.'posts AS p INNER JOIN '.$db->prefix.'topics AS t ON p.topic_id=t.id WHERE p.id IN('.$search_results.') ORDER BY '.$sql; + else + $sql = 'SELECT t.id AS tid, t.poster, t.subject, t.last_post, t.last_post_id, t.last_poster, t.num_replies, t.forum_id FROM '.$db->prefix.'posts AS p INNER JOIN '.$db->prefix.'topics AS t ON p.topic_id=t.id WHERE t.id IN('.$search_results.') GROUP BY t.id, t.poster, t.subject, t.last_post, t.last_post_id, t.last_poster, t.num_replies, t.forum_id'.$group_by.' ORDER BY '.$sql; + + $per_page = ($show_as == 'posts') ? $disp_posts : $disp_topics; + + // The number of pages required to display all results (depending on $disp_topics setting) + $num_pages = ceil($num_hits / $per_page); + + if (!isset($_GET['p']) || $_GET['p'] <= 1 || $_GET['p'] > $num_pages) + { + $p = 1; + $start_from = 0; + } + else + { + $p = $_GET['p']; + $start_from = $per_page * ($p - 1); + } + + + $sql .= ' '.$sort_dir.' LIMIT '.$start_from.', '.$per_page; + + $result = $db->query($sql) or error('Unable to fetch search results', __FILE__, __LINE__, $db->error()); + + $search_set = array(); + while ($row = $db->fetch_assoc($result)) + $search_set[] = $row; + + $db->free_result($result); + + + $page_title = htmlspecialchars($options['board_title']).' / '.$lang_search['Search results']; + require 'header.php'; + +?> +
 
+ + + + + + + + + + +'.$temp[1].''; + } + + if ($options['censoring'] == '1') + $search_set[$i]['subject'] = censor_words($search_set[$i]['subject']); + + $subject = ''.htmlspecialchars($search_set[$i]['subject']).''; + + if (!$cookie['is_guest'] && $search_set[$i]['last_post'] > $cookie['last_timeout']) + { + if ($cur_user['show_img'] != '0') + $icon = ''; + else + $icon = ''; + + $subject = ''.$subject.''; + } + else + $icon = ' '; + + if ($show_as == 'posts') + { + if ($options['censoring'] == '1') + $search_set[$i]['message'] = censor_words($search_set[$i]['message']); + + $message = str_replace("\n", '
', htmlspecialchars($search_set[$i]['message'])); + $pposter = htmlspecialchars($search_set[$i]['pposter']); + + if ($search_set[$i]['poster_id'] > 1) + $pposter = ''.$pposter.''; + + if (strlen($message) == 140) + $message .= ' ...'; + +?> + + + + + + + + + + + + + + + + + + +
 
+ :
+ :

+ + + + +
+ +
+
+
'.format_time($search_set[$i]['last_post']).' '.$lang_common['by'].' '.htmlspecialchars($search_set[$i]['last_poster']) ?>
'.format_time( $search_set[$i]['last_post']).' '.$lang_common['by'].' '.htmlspecialchars($search_set[$i]['last_poster']) ?>
+ + + + + +
+ +
 
+ + + +
 
+ + +. + + +. + + \ No newline at end of file diff --git a/userlist.php b/userlist.php new file mode 100644 index 0000000..83ba297 --- /dev/null +++ b/userlist.php @@ -0,0 +1,197 @@ +'.$lang_common['Login'].' '.$lang_common['or'].' '.$lang_common['register'].'.'); + + +// Load the userlist.php language file +require 'lang/'.$language.'/'.$language.'_userlist.php'; + +$page_title = htmlspecialchars($options['board_title']).' / '.$lang_ul['User list']; +require 'header.php'; + + +$id = isset($_GET['id']); +if ($id != 'other' && $id != 'all' && !preg_match('/^[a-zA-Z]$/', $id)) + $id = 'A'; + +?> +
 
+ + + + + + + + +
+'.chr($i).'  '; + else + print ''.chr($i).'  '; +} +print "\n"; + +?> + '.$lang_ul['Other'].''."\n" : $lang_ul['Other']."\n"; ?>  '.$lang_ul['All users'].''."\n" : $lang_ul['All users']."\n"; ?> +
+ +
 
+ + + + + + + + + + +
+ + + + + + + +query('SELECT COUNT(id)-1 FROM '.$db->prefix.'users') or error('Unable to fetch user list count', __FILE__, __LINE__, $db->error()); +else if ($id == 'other') +{ + switch ($db_type) + { + case 'mysql': + $result = $db->query('SELECT COUNT(id) FROM '.$db->prefix.'users WHERE id>1 AND username NOT REGEXP \'^[a-zA-Z]\'') or error('Unable to fetch user list count', __FILE__, __LINE__, $db->error()); + break; + + case 'pgsql'; + $result = $db->query('SELECT COUNT(id) FROM '.$db->prefix.'users WHERE id>1 AND username !~ \'^[a-zA-Z]\'') or error('Unable to fetch user list count', __FILE__, __LINE__, $db->error()); + break; + } +} +else + $result = $db->query('SELECT COUNT(id) FROM '.$db->prefix.'users WHERE id>1 AND username LIKE \''.$id.'%\'') or error('Unable to fetch user list count', __FILE__, __LINE__, $db->error()); +$num_users = $db->result($result, 0); + + +// The number of pages required to display all users +$num_pages = ceil($num_users / 50); + +if (!isset($_GET['p']) || $_GET['p'] <= 1 || $_GET['p'] > $num_pages) +{ + $p = 1; + $start_from = 0; +} +else +{ + $p = $_GET['p']; + $start_from = 50 * ($p - 1); +} + + +if ($id == 'all') + $result = $db->query('SELECT id, username, email, title, hide_email, num_posts, status, registered FROM '.$db->prefix.'users WHERE id>1 ORDER BY username LIMIT '.$start_from.', 50') or error('Unable to fetch user list', __FILE__, __LINE__, $db->error()); +else if ($id == 'other') +{ + switch ($db_type) + { + case 'mysql': + $result = $db->query('SELECT id, username, email, title, hide_email, num_posts, status, registered FROM '.$db->prefix.'users WHERE id>1 AND username NOT REGEXP \'^[a-zA-Z]\' ORDER BY username LIMIT '.$start_from.', 50') or error('Unable to fetch user list', __FILE__, __LINE__, $db->error()); + break; + + case 'pgsql'; + $result = $db->query('SELECT id, username, email, title, hide_email, num_posts, status, registered FROM '.$db->prefix.'users WHERE id>1 AND username !~ \'^[a-zA-Z]\' ORDER BY username LIMIT '.$start_from.', 50') or error('Unable to fetch user list', __FILE__, __LINE__, $db->error()); + break; + } +} +else + $result = $db->query('SELECT id, username, email, title, hide_email, num_posts, status, registered FROM '.$db->prefix.'users WHERE id>1 AND username LIKE \''.$id.'%\' ORDER BY username LIMIT '.$start_from.', 50') or error('Unable to fetch user list', __FILE__, __LINE__, $db->error()); +$num_users_page = $db->num_rows($result); + + +if ($num_users_page) +{ + while ($num_users_page--) + { + $user_data = $db->fetch_assoc($result); + + $user_title = get_title($user_data); + +?> + + + + + + 0): ?> + +'."\n"; + +?> +
'.htmlspecialchars($user_data['username']).'' ?> 0) ? ''.$user_data['email'].'' : $lang_ul['Not displayed']; ?>
'.$lang_ul['No users'].' "'.$id.'".
+ + + + + +
+'.$lang_common['Login'].' '.$lang_common['or'].' '.$lang_common['register'].'.'); + + +if (!$cookie['is_guest']) +{ + $disp_topics = $cur_user['disp_topics']; + $disp_posts = $cur_user['disp_posts']; +} +else +{ + $disp_topics = $options['disp_topics_default']; + $disp_posts = $options['disp_posts_default']; +} + +$id = intval($_GET['id']); +if (empty($id) || $id < 0) + message($lang_common['Bad request']); + +// Load the viewforum.php language file +require 'lang/'.$language.'/'.$language.'_forum.php'; + +// Fetch some info from the forum +$result = $db->query('SELECT forum_name, moderators, num_topics, closed, admmod_only FROM '.$db->prefix.'forums WHERE id='.$id) or error('Unable to fetch forum info', __FILE__, __LINE__, $db->error()); +if (!$db->num_rows($result)) + message($lang_common['Bad request'], true); + +list($forum_name, $moderators, $num_topics, $closed, $admmod_only) = $db->fetch_row($result); + +if ($admmod_only == '1' && $cur_user['status'] < 1) + message($lang_common['Bad request']); + +$mods_array = array(); +if ($moderators != '') +{ + $mods_array = unserialize($moderators); + + while (list($mod_username, $mod_id) = @each($mods_array)) + $temp_array[] = ''.htmlspecialchars($mod_username).''; + + $mods_string = implode(', ', $temp_array); +} + +if ($closed != '1') +{ + if ($permissions['guests_post_topic'] == '0' && $cookie['is_guest'] || $permissions['users_post_topic'] == '0' && $cur_user['status'] < 1) + $post_link = ' '; + else + $post_link = ''.$lang_forum['Post topic'].''; +} +else +{ + if ($cur_user['status'] > 1 || $cur_user['status'] == 1 && array_key_exists($cur_user['username'], $mods_array)) + $post_link = $lang_forum['Forum closed'].' / '.$lang_forum['Post topic'].''; + else + $post_link = $lang_forum['Forum closed']; +} + + +$page_title = htmlspecialchars($options['board_title']).' / '.htmlspecialchars($forum_name); +require 'header.php'; + +?> + + + + + + +
/
+ + + + + + + + + + + $num_pages) +{ + $p = 1; + $start_from = 0; +} +else +{ + $p = $_GET['p']; + $start_from = $disp_topics * ($p - 1); +} + + +// Fetch topics (with or without "the dot") +if ($cookie['is_guest'] || $options['show_dot'] == '0') +{ + // Without "the dot" + $result = $db->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='.$id.' ORDER BY sticky DESC, last_post DESC LIMIT '.$start_from.', '.$disp_topics) or error('Unable to fetch topic list for forum', __FILE__, __LINE__, $db->error()); +} +else +{ + // Fetch topic ID's + $result = $db->query('SELECT id FROM '.$db->prefix.'topics WHERE forum_id='.$id.' ORDER BY sticky DESC, last_post DESC LIMIT '.$start_from.', '.$disp_topics) or error('Unable to fetch topic list for forum', __FILE__, __LINE__, $db->error()); + + $threadids = '0'; + while ($row = $db->fetch_row($result)) + $threadids .= ','.$row[0]; + + // Fetch topics + $result = $db->query('SELECT DISTINCT p.poster_id AS has_posted, t.id, t.poster, t.subject, t.posted, t.last_post, t.last_post_id, t.last_poster, t.num_views, t.num_replies, t.closed, t.sticky, t.moved_to FROM '.$db->prefix.'topics AS t LEFT JOIN '.$db->prefix.'posts AS p ON t.id=p.topic_id AND p.poster_id='.$cur_user['id'].' WHERE t.id IN('.$threadids.') ORDER BY sticky DESC, last_post DESC') 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)) +{ + while ($cur_topic = $db->fetch_assoc($result)) + { + if ($cur_topic['moved_to'] == null) + $last_post = ''.format_time($cur_topic['last_post']).' '.$lang_common['by'].' '.htmlspecialchars($cur_topic['last_poster']); + else + $last_post = ' '; + + if ($options['censoring'] == '1') + $cur_topic['subject'] = censor_words($cur_topic['subject']); + + if ($cur_topic['moved_to'] != 0) + $subject = $lang_forum['Moved'].': '.htmlspecialchars($cur_topic['subject']).''; + else if ($cur_topic['closed'] != '1' && $closed != '1') + $subject = ''.htmlspecialchars($cur_topic['subject']).''; + else + $subject = ''.htmlspecialchars($cur_topic['subject']).''; + + if (!$cookie['is_guest'] && $cur_topic['last_post'] > $cookie['last_timeout'] && $cur_topic['moved_to'] == null) + { + if ($cur_user['show_img'] != '0') + $icon = ''; + else + $icon = ''; + + $subject = ''.$subject.''; + } + else + $icon = ' '; + + // Should we display the dot or not? :) + if (!$cookie['is_guest'] && $options['show_dot'] == '1') + { + if ($cur_topic['has_posted'] == $cur_user['id']) + $subject = '· '.$subject; + else + $subject = '  '.$subject; + } + + if ($cur_topic['sticky'] == '1') + $subject = $lang_forum['Sticky'].': '.$subject; + + $num_pages_topic = ceil(($cur_topic['num_replies'] + 1) / $disp_posts); + + if ($num_pages_topic > 1) + { + $stop = ($num_pages_topic < 3) ? ($num_pages_topic + 1) : 4; + + $subject .= '  ['; + for ($current=1; $current < $stop; $current++) + $subject .= ' '.$current.''; + + if ($num_pages_topic > 3) + $subject .= ' - '.$lang_common['Last page'].' ]'; + else + $subject .= ' ]'; + } + +?> + + + + + + + + +'."\n"; + +?> +
 
'.$lang_forum['Empty forum'].'
+ + + + + + +
+'.$lang_common['Login'].' '.$lang_common['or'].' '.$lang_common['register'].'.'); +} + +if ($cookie['is_guest']) { + $disp_posts = $options['disp_posts_default']; +} else { + $disp_posts = $cur_user['disp_posts']; +} + +if (isset($_GET['id'])) { + $id = filter_var($_GET['id'], FILTER_VALIDATE_INT); +} else { + $id = 0; // or some other default value +} + +if (isset($_GET['pid'])) { + $pid = filter_var($_GET['pid'], FILTER_VALIDATE_INT); +} else { + $pid = 0; // or some other default value +} + +if ($id < 0 && $pid < 0) { + message($lang_common['Bad request']); +} + + +// Load the viewtopic.php language file +require 'lang/'.$language.'/'.$language.'_topic.php'; + +// If a pid (post ID) is specified we find out the topic ID and page in that topic +// so we can redirect to the correct message +if (isset($_GET['pid'])) +{ + $pid = $_GET['pid']; + + $result = $db->query('SELECT topic_id FROM '.$db->prefix.'posts WHERE id='.$pid) or error('Unable to fetch post info', __FILE__, __LINE__, $db->error()); + if (!$db->num_rows($result)) + message($lang_common['Bad request']); + + $id = $db->result($result, 0); + + // Determine on what page the post is located (depending on $disp_posts) + $result = $db->query('SELECT id FROM '.$db->prefix.'posts WHERE topic_id='.$id.' ORDER BY posted') or error('Unable to fetch post info', __FILE__, __LINE__, $db->error()); + $num_posts = $db->num_rows($result); + + for ($i = 0; $i < $num_posts; $i++) + { + $curid = $db->result($result, $i); + if ($curid == $pid) + break; + } + $i++; // we started at 0 + + $_GET['p'] = ceil($i / $disp_posts); +} + + +// Fetch some info from the topic +$result = $db->query('SELECT subject, closed, sticky, subscribers, num_replies, forum_id FROM '.$db->prefix.'topics WHERE id='.$id.' AND 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']); + +list($subject, $closed, $sticky, $subscribers, $num_replies, $forum_id) = $db->fetch_row($result); + + +$result = $db->query('SELECT forum_name, moderators, closed, admmod_only FROM '.$db->prefix.'forums WHERE id='.$forum_id) or error('Unable to fetch forum info', __FILE__, __LINE__, $db->error()); +list($forum_name, $moderators, $forum_closed, $admmod_only) = $db->fetch_row($result); + +$mods_array = array(); +if ($moderators != '') +{ + $mods_array = unserialize($moderators); + + while (list($mod_username, $mod_id) = @each($mods_array)) + $temp_array[] = ''.htmlspecialchars($mod_username).''; + + $mods_string = implode(', ', $temp_array); +} + + +if (isset($cur_user['status']) == 2 || (isset($cur_user['status']) == 1 && array_key_exists($cur_user['username'], $mods_array))) + $is_admmod = true; +else + $is_admmod = false; + +if ($admmod_only == '1' && $cur_user['status'] < 1) + message($lang_common['Bad request']); + +if ($closed != '1' && $forum_closed != '1') +{ + if ($permissions['guests_post'] == '0' && $cookie['is_guest'] || $permissions['users_post'] == '0' && $cur_user['status'] < 1) + $post_link = ' '; + else + $post_link = ''.$lang_topic['Post reply'].''; +} +else +{ + if ($is_admmod) + $post_link = $lang_topic['Topic closed'].' / '.$lang_topic['Post reply'].''; + else + $post_link = $lang_topic['Topic closed']; +} + + +$num_pages = ceil(($num_replies + 1) / $disp_posts); + +if (!isset($_GET['p']) || $_GET['p'] <= 1 || $_GET['p'] > $num_pages) +{ + $p = 1; + $start_from = 0; +} +else +{ + $p = $_GET['p']; + $start_from = $disp_posts * ($p - 1); +} + + +$pages = paginate($num_pages, $p, 'viewtopic.php?id='.$id); + + +if ($options['censoring'] == '1') + $subject = censor_words($subject); + + +$page_title = htmlspecialchars($options['board_title']).' / '.$subject; + +$validate_form = ($options['quickpost'] == '1') ? true : false; +require 'header.php'; + +?> + + + + + + +
/ /
+ + + + + + +
+ + + + + +
+
+ +query('SELECT user_id FROM '.$db->prefix.'online WHERE user_id>0') or error('Unable to fetch online list', __FILE__, __LINE__, $db->error()); +$num_online = $db->num_rows($result); + +for ($i = 0; $i < $num_online; $i++) + $online_list[] = $db->result($result, $i); + + +require 'include/parser.php'; + +// Used for switching background color in posts +$bg_switch = true; + + +// Retrieve the topic posts (and their respective poster) +$result = $db->query('SELECT u.email, u.title, u.url, u.location, u.use_avatar, u.signature, u.hide_email, u.num_posts, u.status, u.registered, u.admin_note, p.id, p.poster, p.poster_id, p.poster_ip, p.poster_email, p.message, p.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 WHERE p.topic_id='.$id.' ORDER BY p.posted LIMIT '.$start_from.','.$disp_posts) or error('Unable to fetch post info', __FILE__, __LINE__, $db->error()); + +while ($cur_post = $db->fetch_assoc($result)) +{ + // If the poster is a registered user. + if ($cur_post['poster_id'] > 1) + { + $registered = date($options['date_format'], $cur_post['registered']); + + if (isset($online_list) && in_array($cur_post['poster_id'], $online_list)) + $info = ''.htmlspecialchars($cur_post['poster']).''; + else + $info = ''.htmlspecialchars($cur_post['poster']).''; + + // getTitle() requires that an element 'username' be present in the array + $cur_post['username'] = $cur_post['poster']; + $user_title = get_title($cur_post); + + if ($options['censoring'] == '1') + $user_title = censor_words($user_title); + + $info .= '
'."\n\t\t\t\t\t\t".$user_title.'
'; + + if ($options['avatars'] == '1' && $cur_post['use_avatar'] == '1') + { + if ($img_size = @getimagesize($options['avatars_dir'].'/'.$cur_post['poster_id'].'.gif')) + $info .= "\n\t\t\t\t\t\t".'
'; + else if ($img_size = @getimagesize($options['avatars_dir'].'/'.$cur_post['poster_id'].'.jpg')) + $info .= "\n\t\t\t\t\t\t".'
'; + else if ($img_size = @getimagesize($options['avatars_dir'].'/'.$cur_post['poster_id'].'.png')) + $info .= "\n\t\t\t\t\t\t".'
'; + else + $info .= '
'."\n\t\t\t\t\t\t"; + } + else + $info .= '
'."\n\t\t\t\t\t\t"; + + if ($cur_post['location'] != '') + { + if ($options['censoring'] == '1') + $cur_post['location'] = censor_words($cur_post['location']); + + $info .= $lang_topic['From'].': '.htmlspecialchars($cur_post['location']).'
'."\n\t\t\t\t\t\t"; + } + + $info .= $lang_common['Registered'].': '.$registered.'
'; + + if ($options['show_post_count'] == '1') + $info .= "\n\t\t\t\t\t\t".$lang_common['Posts'].': '.$cur_post['num_posts']; + + if (isset($cur_user['status']) > 0) + { + $info .= '
'."\n\t\t\t\t\t\t".'IP: '.$cur_post['poster_ip'].''; + + if ($cur_post['admin_note'] != '') + $info .= '

'."\n\t\t\t\t\t\t".$lang_topic['Note'].': '.$cur_post['admin_note'].''; + } + + // Generate the string for the links that appear at the bottom of every message. + $links = array(); + + if ($cur_post['hide_email'] == '0') + $links[] = ''.$lang_common['E-mail'].''; + + if ($cur_post['url'] != '') + { + if ($cur_user['link_to_new_win'] == '0') + $links[] = ''.$lang_topic['Website'].''; + else + $links[] = ''.$lang_topic['Website'].''; + } + } + // If the poster is a guest (or a user that has been deleted) + else + { + $info = ''.htmlspecialchars($cur_post['poster']).'
'."\n\t\t\t\t\t\t".$lang_topic['Guest']; + + if (isset($cur_user['status']) > 0) + $info .= '

'."\n\t\t\t\t\t\t".'IP: '.$cur_post['poster_ip'].'

'; + else + $info .= '



'; + + if ($cur_post['poster_email'] != '') + $links = array(''.$lang_common['E-mail'].''); + else + $links = array(); + } + + + if ($cur_post['edited']) + $edited = $lang_topic['Last edit'].' '.htmlspecialchars($cur_post['edited_by']).' ('.format_time($cur_post['edited']).')'; + else + $edited = ' '; + + + $actions = array(); + + if (!$is_admmod) + { + if (!$cookie['is_guest']) + { + $actions[] = ''.$lang_topic['Report'].''; + + if ($closed != '1' && $forum_closed != '1') + { + if ($permissions['users_edit_post'] == '1' && $cur_post['poster_id'] == $cur_user['id']) + { + if ($permissions['users_del_post'] == '1') + $actions[] = ''.$lang_topic['Delete'].''; + + $actions[] = ''.$lang_topic['Edit'].''; + } + + $actions[] = ''.$lang_topic['Quote'].''; + } + } + else + { + if ($permissions['guests_post'] == '1' && $closed != '1' && $forum_closed != '1') + $actions[] = ''.$lang_topic['Quote'].''; + } + } + else + $actions[] = ''.$lang_topic['Report'].' | '.$lang_topic['Delete'].' | '.$lang_topic['Edit'].' | '.$lang_topic['Quote'].''; + + + // Switch the background color for every message. + $bg_switch = ($bg_switch) ? $bg_switch = false : $bg_switch = true; + + // Perform the main parsing of the message (BBCode, smilies, censor words etc) + $cur_post['message'] = parse_message($cur_post['message'], $cur_post['smilies']); + + + if ($cur_post['signature'] != '' && $cur_user['show_sig'] != '0') + $signature = '

_______________________________________
'.parse_signature($cur_post['signature']).'

'; + else + $signature = NULL; + +?> +
+ + + + + + + + + + +
+ + + + +
+
+ +
+
+
+ + + + +
+ '.$signature.''."\n" : '

'."\n"; ?> +
+
+ + + + + + +
0) ? implode(' | ', $links) : ' '; ?> 0) ? implode(' | ', $actions) : ' '; ?>
+
+ +'.$lang_topic['Unsubscribe'].''; + else + $subscraction = ''.$lang_topic['Subscribe'].''; +} +else + $subscraction = ' '; + + +?> + + + + + + +
+ + +
+ + + + + + + + + + + + + + + + +
+   

+ HTML:   
+ BBCode:   
+ [img] tag:   
+ Smilies:    +
 
  
  

+
+ +
 
+query('UPDATE '.$db->prefix.'topics SET num_views=num_views+1 WHERE id='.$id) or error('Unable to update topic', __FILE__, __LINE__, $db->error()); + +$footer_style = 'topic'; +require 'footer.php';