# HG changeset patch # User Dan # Date 1184202108 14400 # Node ID f9ffdbd966071f6a7dd90966e827b3b7f9216d03 Initial population diff -r 000000000000 -r f9ffdbd96607 plugins/PunBB.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugins/PunBB.php Wed Jul 11 21:01:48 2007 -0400 @@ -0,0 +1,1 @@ + diff -r 000000000000 -r f9ffdbd96607 punbb/COPYING --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/punbb/COPYING Wed Jul 11 21:01:48 2007 -0400 @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + 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 -r 000000000000 -r f9ffdbd96607 punbb/admin_bans.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/punbb/admin_bans.php Wed Jul 11 21:01:48 2007 -0400 @@ -0,0 +1,362 @@ + PUN_MOD || ($pun_user['g_id'] == PUN_MOD && $pun_config['p_mod_ban_users'] == '0')) + message($lang_common['No permission']); + + +// Add/edit a ban (stage 1) +if (isset($_REQUEST['add_ban']) || isset($_GET['edit_ban'])) +{ + if (isset($_GET['add_ban']) || isset($_POST['add_ban'])) + { + // If the id of the user to ban was provided through GET (a link from profile.php) + if (isset($_GET['add_ban'])) + { + $add_ban = intval($_GET['add_ban']); + if ($add_ban < 2) + message($lang_common['Bad request']); + + $user_id = $add_ban; + + $result = $db->query('SELECT group_id, username, email FROM '.$db->prefix.'users WHERE id='.$user_id) or error('Unable to fetch user info', __FILE__, __LINE__, $db->error()); + if ($db->num_rows($result)) + list($group_id, $ban_user, $ban_email) = $db->fetch_row($result); + else + message('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, group_id, username, email FROM '.$db->prefix.'users WHERE username=\''.$db->escape($ban_user).'\' AND id>1') or error('Unable to fetch user info', __FILE__, __LINE__, $db->error()); + if ($db->num_rows($result)) + list($user_id, $group_id, $ban_user, $ban_email) = $db->fetch_row($result); + else + message('No user by that username registered. If you want to add a ban not tied to a specific username just leave the username blank.'); + } + } + + // Make sure we're not banning an admin + if (isset($group_id) && $group_id == PUN_ADMIN) + message('The user '.pun_htmlspecialchars($ban_user).' is an administrator and can\'t be banned. If you want to ban an administrator, you must first demote him/her to moderator or user.'); + + // If we have a $user_id, we can try to find the last known IP of that user + if (isset($user_id)) + { + $result = $db->query('SELECT poster_ip FROM '.$db->prefix.'posts WHERE poster_id='.$user_id.' ORDER BY posted DESC LIMIT 1') or error('Unable to fetch post info', __FILE__, __LINE__, $db->error()); + $ban_ip = ($db->num_rows($result)) ? $db->result($result) : ''; + } + + $mode = 'add'; + } + else // We are editing a ban + { + $ban_id = intval($_GET['edit_ban']); + if ($ban_id < 1) + message($lang_common['Bad request']); + + $result = $db->query('SELECT username, ip, email, message, expire FROM '.$db->prefix.'bans WHERE id='.$ban_id) or error('Unable to fetch ban info', __FILE__, __LINE__, $db->error()); + if ($db->num_rows($result)) + list($ban_user, $ban_ip, $ban_email, $ban_message, $ban_expire) = $db->fetch_row($result); + else + message($lang_common['Bad request']); + + $ban_expire = ($ban_expire != '') ? date('Y-m-d', $ban_expire) : ''; + + $mode = 'edit'; + } + + $page_title = pun_htmlspecialchars($pun_config['o_board_title']).' / Admin / Bans'; + $focus_element = array('bans2', 'ban_user'); + require PUN_ROOT.'header.php'; + + generate_admin_menu('bans'); + + +?> +
+

Ban advanced settings

+
+
+
+ + +
+ Supplement ban with IP and e-mail +
+ + + + + + + + + + + + + +
Username + + The username to ban. +
IP-adresses + + The IP or IP-ranges you wish to ban (e.g. 150.11.110.1 or 150.11.110). Separate addresses with spaces. If an IP is entered already it is the last known IP of this user in the database.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 "Allow banned e-mail addresses" in Options for more info. +
+

You should be very careful when banning an IP-range because of the possibility of multiple users matching the same partial IP.

+
+
+
+
+
+ Ban message and expiry +
+ + + + + + + + + +
Ban message + + A message that will be displayed to the banned user when he/she visits the forums. +
Expire date + + The date when this ban should be automatically removed (format: YYYY-MM-DD). Leave blank to remove manually. +
+
+
+
+

+
+
+
+
+ + 1) ? ltrim($octets[$c], "0") : $octets[$c]; + + if ($c > 3 || preg_match('/[^0-9]/', $octets[$c]) || intval($octets[$c]) > 255) + message('You entered an invalid IP/IP-range.'); + } + + $cur_address = implode('.', $octets); + $addresses[$i] = $cur_address; + } + + $ban_ip = implode(' ', $addresses); + } + + require PUN_ROOT.'include/email.php'; + if ($ban_email != '' && !is_valid_email($ban_email)) + { + if (!preg_match('/^[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,4})$/', $ban_email)) + message('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 in the future.'); + } + else + $ban_expire = 'NULL'; + + $ban_user = ($ban_user != '') ? '\''.$db->escape($ban_user).'\'' : 'NULL'; + $ban_ip = ($ban_ip != '') ? '\''.$db->escape($ban_ip).'\'' : 'NULL'; + $ban_email = ($ban_email != '') ? '\''.$db->escape($ban_email).'\'' : 'NULL'; + $ban_message = ($ban_message != '') ? '\''.$db->escape($ban_message).'\'' : 'NULL'; + + if ($_POST['mode'] == 'add') + $db->query('INSERT INTO '.$db->prefix.'bans (username, ip, email, message, expire) VALUES('.$ban_user.', '.$ban_ip.', '.$ban_email.', '.$ban_message.', '.$ban_expire.')') or error('Unable to add ban', __FILE__, __LINE__, $db->error()); + else + $db->query('UPDATE '.$db->prefix.'bans SET username='.$ban_user.', ip='.$ban_ip.', email='.$ban_email.', message='.$ban_message.', expire='.$ban_expire.' WHERE id='.intval($_POST['ban_id'])) or error('Unable to update ban', __FILE__, __LINE__, $db->error()); + + // Regenerate the bans cache + require_once PUN_ROOT.'include/cache.php'; + generate_bans_cache(); + + redirect('admin_bans.php', 'Ban '.(($_POST['mode'] == 'edit') ? 'edited' : 'added').'. Redirecting …'); +} + + +// Remove a ban +else if (isset($_GET['del_ban'])) +{ + confirm_referrer('admin_bans.php'); + + $ban_id = intval($_GET['del_ban']); + if ($ban_id < 1) + message($lang_common['Bad request']); + + $db->query('DELETE FROM '.$db->prefix.'bans WHERE id='.$ban_id) or error('Unable to delete ban', __FILE__, __LINE__, $db->error()); + + // Regenerate the bans cache + require_once PUN_ROOT.'include/cache.php'; + generate_bans_cache(); + + redirect('admin_bans.php', 'Ban removed. Redirecting …'); +} + + +$page_title = pun_htmlspecialchars($pun_config['o_board_title']).' / Admin / Bans'; +$focus_element = array('bans', 'new_ban_user'); +require PUN_ROOT.'header.php'; + +generate_admin_menu('bans'); + +?> +
+

New ban

+
+
+
+
+ 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. +
+
+
+
+
+
+ +

Existing bans

+
+
+query('SELECT id, username, ip, email, message, expire FROM '.$db->prefix.'bans ORDER BY id') or error('Unable to fetch 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); + +?> +
+
+ Ban expires: +
+ + + + + + + + + + + + + + + + + +
Username
E-mail
IP/IP-ranges
Reason
+

Edit - Remove

+
+
+
+No bans in list.

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

Category delete

+
+
+
+ +
+ Confirm delete category +
+

Are you sure that you want to delete the category ""?

+

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

+
+
+
+

Go back

+
+
+
+
+ +query('SELECT id, disp_position FROM '.$db->prefix.'categories ORDER BY disp_position') or error('Unable to fetch category list', __FILE__, __LINE__, $db->error()); + $num_cats = $db->num_rows($result); + + for ($i = 0; $i < $num_cats; ++$i) + { + if ($cat_name[$i] == '') + message('You must enter a category name.'); + + if (!@preg_match('#^\d+$#', $cat_order[$i])) + message('Position must be an integer value.'); + + list($cat_id, $position) = $db->fetch_row($result); + + $db->query('UPDATE '.$db->prefix.'categories SET cat_name=\''.$db->escape($cat_name[$i]).'\', disp_position='.$cat_order[$i].' WHERE id='.$cat_id) or error('Unable to update category', __FILE__, __LINE__, $db->error()); + } + + // Regenerate the quickjump cache + require_once PUN_ROOT.'include/cache.php'; + generate_quickjump_cache(); + + redirect('admin_categories.php', 'Categories updated. Redirecting …'); +} + + +// Generate an array with all categories +$result = $db->query('SELECT id, cat_name, disp_position FROM '.$db->prefix.'categories ORDER BY disp_position') or error('Unable to fetch category list', __FILE__, __LINE__, $db->error()); +$num_cats = $db->num_rows($result); + +for ($i = 0; $i < $num_cats; ++$i) + $cat_list[] = $db->fetch_row($result); + + +$page_title = pun_htmlspecialchars($pun_config['o_board_title']).' / Admin / Categories'; +require PUN_ROOT.'header.php'; + +generate_admin_menu('categories'); + +?> +
+

Add/remove/edit categories

+
+
+
+
+ Add/delete categories +
+ + + + + + + + + +
Add a new category
+ + The name of the new category you want to add. You can edit the name of the category later (see below).Go to Forums to add forums to your new category. +
Delete a category
+ + Select the name of the category you want to delete. You will be asked to confirm your choice of category for deletion before it is deleted. +
+
+
+
+
+
+ Edit categories +
+ + + + + + + + + + + + + +
NamePosition 
 
+
+
+
+
+
+
+
+
+ + PUN_MOD) + message($lang_common['No permission']); + + +// Add a censor word +if (isset($_POST['add_word'])) +{ + confirm_referrer('admin_censoring.php'); + + $search_for = trim($_POST['new_search_for']); + $replace_with = trim($_POST['new_replace_with']); + + if ($search_for == '' || $replace_with == '') + message('You must enter both a word to censor and text to replace it with.'); + + $db->query('INSERT INTO '.$db->prefix.'censoring (search_for, replace_with) VALUES (\''.$db->escape($search_for).'\', \''.$db->escape($replace_with).'\')') or error('Unable to add censor word', __FILE__, __LINE__, $db->error()); + + redirect('admin_censoring.php', 'Censor word added. Redirecting …'); +} + + +// Update a censor word +else if (isset($_POST['update'])) +{ + confirm_referrer('admin_censoring.php'); + + $id = intval(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=\''.$db->escape($search_for).'\', replace_with=\''.$db->escape($replace_with).'\' WHERE id='.$id) or error('Unable to update censor word', __FILE__, __LINE__, $db->error()); + + redirect('admin_censoring.php', 'Censor word updated. Redirecting …'); +} + + +// Remove a censor word +else if (isset($_POST['remove'])) +{ + confirm_referrer('admin_censoring.php'); + + $id = intval(key($_POST['remove'])); + + $db->query('DELETE FROM '.$db->prefix.'censoring WHERE id='.$id) or error('Unable to delete censor word', __FILE__, __LINE__, $db->error()); + + redirect('admin_censoring.php', 'Censor word removed. Redirecting …'); +} + + +$page_title = pun_htmlspecialchars($pun_config['o_board_title']).' / Admin / Censoring'; +$focus_element = array('censoring', 'new_search_for'); +require PUN_ROOT.'header.php'; + +generate_admin_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.

+ + + + + + + + + + + + + + + +
Censored wordReplacement textAction
+
+
+
+
+
+ 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)) +{ + +?> + + + + + + + + + +fetch_assoc($result)) + echo "\t\t\t\t\t\t\t\t".''."\n"; + +?> + +
Censored wordReplacement textActions
 
+No censor words in list.

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

Confirm delete forum

+
+
+
+
+ Important! Read before deleting +
+

Are you sure that you want to delete the forum ""?

+

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

+
+
+
+

Go back

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

Edit forum

+
+
+

+
+
+ Edit forum details +
+ + + + + + + + + + + + + + + + + + + + + +
Forum name
Description (HTML)
Category + +
Sort topics by + +
Redirect URL'; ?>
+
+
+
+
+
+ Edit group permissions for this forum +
+

In this form, you can set the forum specific permissions for the different user groups. If you haven't made any changes to this forums group permissions, what you see below is the default based on settings in User groups. Administrators always have full permissions and are thus excluded. Permission settings that differ from the default permissions for the user group are marked red. The "Read forum" permission checkbox will be disabled if the group in question lacks the "Read board" permission. For redirect forums, only the "Read forum" permission is editable.

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

+
+
+
+
+ + + +
+

Add forum

+
+
+
+
+ Create a new forum +
+ + + + + +
Add forum to category
+ + Select the category to which you wish to add a new forum. +
+
+
+
+
+
+ +

Edit forums

+
+
+

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

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

Group settings

+
+
+

+
+ + + +
+ Setup group options and permissions +
+

Below options and permissions are the default permissions for the user group. These options apply if no forum specific permissions are in effect.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Group title + +
User title + + This title will override any rank users in this group have attained. Leave blank to use default title or rank. +
Read board + tabindex="3" /> Yes    tabindex="4" /> No + Allow users in this group to view the board. This setting applies to every aspect of the board and can therefore not be overridden by forum specific settings. If this is set to "No", users in this group will only be able to login/logout and register. +
Post replies + tabindex="5" /> Yes    tabindex="6" /> No + Allow users in this group to post replies in topics. +
Post topics + tabindex="7" /> Yes    tabindex="8" /> No + Allow users in this group to post new topics. +
Edit posts + tabindex="11" /> Yes    tabindex="12" /> No + Allow users in this group to edit their own posts. +
Delete posts + tabindex="13" /> Yes    tabindex="14" /> No + Allow users in this group to delete their own posts. +
Delete topics + tabindex="15" /> Yes    tabindex="16" /> No + Allow users in this group to delete their own topics (including any replies). +
Set user title + tabindex="17" /> Yes    tabindex="18" /> No + Allow users in this group to set their own user title. +
Use search + tabindex="19" /> Yes    tabindex="20" /> No + Allow users in this group to use the search feature. +
Search user list + tabindex="21" /> Yes    tabindex="22" /> No + Allow users in this group to freetext search for users in the user list. +
Edit subjects interval + + Number of seconds after post time that users in this group may edit the subject of topics they've posted. Set to 0 to allow edits indefinitely. +
Post flood interval + + Number of seconds that users in this group have to wait between posts. Set to 0 to disable. +
Search flood interval + + Number of seconds that users in this group have to wait between searches. Set to 0 to disable. +
+

Please note that in order for a user in this group to have moderator abilities, he/she must be assigned to moderate one or more forums. This is done via the user administration page of the user's profile.

+
+
+
+

+
+
+
+
+ +escape($user_title).'\'' : 'NULL'; + + if ($_POST['mode'] == 'add') + { + $result = $db->query('SELECT 1 FROM '.$db->prefix.'groups WHERE g_title=\''.$db->escape($title).'\'') or error('Unable to check group title collision', __FILE__, __LINE__, $db->error()); + if ($db->num_rows($result)) + message('There is already a group with the title \''.pun_htmlspecialchars($title).'\'.'); + + $db->query('INSERT INTO '.$db->prefix.'groups (g_title, g_user_title, g_read_board, g_post_replies, g_post_topics, g_edit_posts, g_delete_posts, g_delete_topics, g_set_title, g_search, g_search_users, g_edit_subjects_interval, g_post_flood, g_search_flood) VALUES(\''.$db->escape($title).'\', '.$user_title.', '.$read_board.', '.$post_replies.', '.$post_topics.', '.$edit_posts.', '.$delete_posts.', '.$delete_topics.', '.$set_title.', '.$search.', '.$search_users.', '.$edit_subjects_interval.', '.$post_flood.', '.$search_flood.')') or error('Unable to add group', __FILE__, __LINE__, $db->error()); + $new_group_id = $db->insert_id(); + + // Now lets copy the forum specific permissions from the group which this group is based on + $result = $db->query('SELECT forum_id, read_forum, post_replies, post_topics FROM '.$db->prefix.'forum_perms WHERE group_id='.intval($_POST['base_group'])) or error('Unable to fetch group forum permission list', __FILE__, __LINE__, $db->error()); + while ($cur_forum_perm = $db->fetch_assoc($result)) + $db->query('INSERT INTO '.$db->prefix.'forum_perms (group_id, forum_id, read_forum, post_replies, post_topics) VALUES('.$new_group_id.', '.$cur_forum_perm['forum_id'].', '.$cur_forum_perm['read_forum'].', '.$cur_forum_perm['post_replies'].', '.$cur_forum_perm['post_topics'].')') or error('Unable to insert group forum permissions', __FILE__, __LINE__, $db->error()); + } + else + { + $result = $db->query('SELECT 1 FROM '.$db->prefix.'groups WHERE g_title=\''.$db->escape($title).'\' AND g_id!='.intval($_POST['group_id'])) or error('Unable to check group title collision', __FILE__, __LINE__, $db->error()); + if ($db->num_rows($result)) + message('There is already a group with the title \''.pun_htmlspecialchars($title).'\'.'); + + $db->query('UPDATE '.$db->prefix.'groups SET g_title=\''.$db->escape($title).'\', g_user_title='.$user_title.', g_read_board='.$read_board.', g_post_replies='.$post_replies.', g_post_topics='.$post_topics.', g_edit_posts='.$edit_posts.', g_delete_posts='.$delete_posts.', g_delete_topics='.$delete_topics.', g_set_title='.$set_title.', g_search='.$search.', g_search_users='.$search_users.', g_edit_subjects_interval='.$edit_subjects_interval.', g_post_flood='.$post_flood.', g_search_flood='.$search_flood.' WHERE g_id='.intval($_POST['group_id'])) or error('Unable to update group', __FILE__, __LINE__, $db->error()); + } + + // Regenerate the quickjump cache + require_once PUN_ROOT.'include/cache.php'; + generate_quickjump_cache(); + + redirect('admin_groups.php', 'Group '.(($_POST['mode'] == 'edit') ? 'edited' : 'added').'. Redirecting …'); +} + + +// Set default group +else if (isset($_POST['set_default_group'])) +{ + confirm_referrer('admin_groups.php'); + + $group_id = intval($_POST['default_group']); + if ($group_id < 4) + message($lang_common['Bad request']); + + $db->query('UPDATE '.$db->prefix.'config SET conf_value='.$group_id.' WHERE conf_name=\'o_default_user_group\'') or error('Unable to update board config', __FILE__, __LINE__, $db->error()); + + // Regenerate the config cache + require_once PUN_ROOT.'include/cache.php'; + generate_config_cache(); + + redirect('admin_groups.php', 'Default group set. Redirecting …'); +} + + +// Remove a group +else if (isset($_GET['del_group'])) +{ + confirm_referrer('admin_groups.php'); + + $group_id = intval($_GET['del_group']); + if ($group_id < 5) + message($lang_common['Bad request']); + + // Make sure we don't remove the default group + if ($group_id == $pun_config['o_default_user_group']) + message('The default group cannot be removed. In order to delete this group, you must first setup a different group as the default.'); + + + // Check if this group has any members + $result = $db->query('SELECT g.g_title, COUNT(u.id) FROM '.$db->prefix.'groups AS g INNER JOIN '.$db->prefix.'users AS u ON g.g_id=u.group_id WHERE g.g_id='.$group_id.' GROUP BY g.g_id, g_title') or error('Unable to fetch group info', __FILE__, __LINE__, $db->error()); + + // If the group doesn't have any members or if we've already selected a group to move the members to + if (!$db->num_rows($result) || isset($_POST['del_group'])) + { + if (isset($_POST['del_group'])) + { + $move_to_group = intval($_POST['move_to_group']); + $db->query('UPDATE '.$db->prefix.'users SET group_id='.$move_to_group.' WHERE group_id='.$group_id) or error('Unable to move users into group', __FILE__, __LINE__, $db->error()); + } + + // Delete the group and any forum specific permissions + $db->query('DELETE FROM '.$db->prefix.'groups WHERE g_id='.$group_id) or error('Unable to delete group', __FILE__, __LINE__, $db->error()); + $db->query('DELETE FROM '.$db->prefix.'forum_perms WHERE group_id='.$group_id) or error('Unable to delete group forum permissions', __FILE__, __LINE__, $db->error()); + + // Regenerate the quickjump cache + require_once PUN_ROOT.'include/cache.php'; + generate_quickjump_cache(); + + redirect('admin_groups.php', 'Group removed. Redirecting …'); + } + + + list($group_title, $group_members) = $db->fetch_row($result); + + $page_title = pun_htmlspecialchars($pun_config['o_board_title']).' / Admin / User groups'; + require PUN_ROOT.'header.php'; + + generate_admin_menu('groups'); + +?> +
+

Remove group

+
+
+
+
+ Move users currently in group +
+

The group "" currently has members. Please select a group to which these members will be assigned upon removal.

+ +
+
+
+

+
+
+
+
+ + +
+

Add/setup groups

+
+
+
+
+ Add new group +
+ + + + + +
Base new group on
+ + Select a user group from which the new group will inherit it's permission settings. The next page will let you fine-tune said settings. +
+
+
+
+
+
+ Set default group +
+ + + + + +
Default group
+ + This is the default user group, e.g. the group users are placed in when they register. For security reasons, users can't be placed in either the moderator or administrator user groups by default. +
+
+
+
+
+
+ +

Existing groups

+
+
+
+
+ Edit/remove groups +
+

The pre-defined groups Guests, Administrators, Moderators and Members cannot be removed. They can however be edited. Please note though, that in some groups, some options are unavailable (e.g. the edit posts permission for guests). Administrators always have full permissions.

+ +query('SELECT g_id, g_title FROM '.$db->prefix.'groups ORDER BY g_id') or error('Unable to fetch user group list', __FILE__, __LINE__, $db->error()); + +while ($cur_group = $db->fetch_assoc($result)) + echo "\t\t\t\t\t\t\t\t".''."\n"; + +?> +
Edit'.(($cur_group['g_id'] > PUN_MEMBER) ? ' - Remove' : '').''.pun_htmlspecialchars($cur_group['g_title']).'
+
+
+
+
+
+
+
+ + PUN_MOD) + message($lang_common['No permission']); + + +$action = isset($_GET['action']) ? $_GET['action'] : null; + +// Check for upgrade +if ($action == 'check_upgrade') +{ + if (!ini_get('allow_url_fopen')) + message('Unable to check for upgrade since \'allow_url_fopen\' is disabled on this system.'); + + $fp = @fopen('http://www.punbb.org/latest_version', 'r'); + $latest_version = trim(@fread($fp, 16)); + @fclose($fp); + + if ($latest_version == '') + message('Check for upgrade failed for unknown reasons.'); + + $cur_version = str_replace(array('.', 'dev', 'beta', ' '), '', strtolower($pun_config['o_cur_version'])); + $cur_version = (strlen($cur_version) == 2) ? intval($cur_version) * 10 : intval($cur_version); + + $latest_version = str_replace('.', '', strtolower($latest_version)); + $latest_version = (strlen($latest_version) == 2) ? intval($latest_version) * 10 : intval($latest_version); + + if ($cur_version >= $latest_version) + message('You are running the latest version of PunBB.'); + else + message('A new version of PunBB has been released. You can download the latest version at PunBB.org.'); +} + + +// Show phpinfo() output +else if ($action == 'phpinfo' && $pun_user['g_id'] == PUN_ADMIN) +{ + // Is phpinfo() a disabled function? + if (strpos(strtolower((string)@ini_get('disable_functions')), 'phpinfo') !== false) + message('The PHP function phpinfo() has been disabled on this server.'); + + phpinfo(); + exit; +} + + +// Get the server load averages (if possible) +if (@file_exists('/proc/loadavg') && is_readable('/proc/loadavg')) +{ + // We use @ just in case + $fh = @fopen('/proc/loadavg', 'r'); + $load_averages = @fread($fh, 64); + @fclose($fh); + + $load_averages = @explode(' ', $load_averages); + $server_load = isset($load_averages[2]) ? $load_averages[0].' '.$load_averages[1].' '.$load_averages[2] : 'Not available'; +} +else if (!in_array(PHP_OS, array('WINNT', 'WIN32')) && preg_match('/averages?: ([0-9\.]+),[\s]+([0-9\.]+),[\s]+([0-9\.]+)/i', @exec('uptime'), $load_averages)) + $server_load = $load_averages[1].' '.$load_averages[2].' '.$load_averages[3]; +else + $server_load = 'Not available'; + + +// Get number of current visitors +$result = $db->query('SELECT COUNT(user_id) FROM '.$db->prefix.'online WHERE idle=0') or error('Unable to fetch online count', __FILE__, __LINE__, $db->error()); +$num_online = $db->result($result); + + +// Get the database system version +switch ($db_type) +{ + case 'sqlite': + $db_version = 'SQLite '.sqlite_libversion(); + break; + + default: + $result = $db->query('SELECT VERSION()') or error('Unable to fetch version info', __FILE__, __LINE__, $db->error()); + $db_version = $db->result($result); + break; +} + + +// Collect some additional info about MySQL +if ($db_type == 'mysql' || $db_type == 'mysqli') +{ + $db_version = 'MySQL '.$db_version; + + // Calculate total db size/row count + $result = $db->query('SHOW TABLE STATUS FROM `'.$db_name.'`') or error('Unable to fetch table status', __FILE__, __LINE__, $db->error()); + + $total_records = $total_size = 0; + while ($status = $db->fetch_assoc($result)) + { + $total_records += $status['Rows']; + $total_size += $status['Data_length'] + $status['Index_length']; + } + + $total_size = $total_size / 1024; + + if ($total_size > 1024) + $total_size = round($total_size / 1024, 2).' MB'; + else + $total_size = round($total_size, 2).' KB'; +} + + +// See if MMCache or PHPA is loaded +if (function_exists('mmcache')) + $php_accelerator = 'Turck MMCache'; +else if (isset($_PHPA)) + $php_accelerator = 'ionCube PHP Accelerator'; +else + $php_accelerator = 'N/A'; + + +$page_title = pun_htmlspecialchars($pun_config['o_board_title']).' / Admin'; +require PUN_ROOT.'header.php'; + +generate_admin_menu('index'); + +?> +
+

Forum administration

+
+
+

+ 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

+
+
+
+
PunBB version
+
+ PunBB - Check for upgrade
+ © Copyright 2002, 2003, 2004, 2005 Rickard Andersson +
+
Server load
+
+ ( users online) +
+
Environment
+
+ Operating system:
+ PHP: - Show info
+ Accelerator: +
+
Database
+
+ +
Rows: +
Size: +
+
+
+
+
+
+ + PUN_MOD) + message($lang_common['No permission']); + + +// The plugin to load should be supplied via GET +$plugin = isset($_GET['plugin']) ? $_GET['plugin'] : ''; +if (!@preg_match('/^AM?P_(\w*?)\.php$/i', $plugin)) + message($lang_common['Bad request']); + +// AP_ == Admins only, AMP_ == admins and moderators +$prefix = substr($plugin, 0, strpos($plugin, '_')); +if ($pun_user['g_id'] == PUN_MOD && $prefix == 'AP') + message($lang_common['No permission']); + +// Make sure the file actually exists +if (!file_exists(PUN_ROOT.'plugins/'.$plugin)) + message('There is no plugin called \''.$plugin.'\' in the plugin directory.'); + +// Construct REQUEST_URI if it isn't set +if (!isset($_SERVER['REQUEST_URI'])) + $_SERVER['REQUEST_URI'] = (isset($_SERVER['PHP_SELF']) ? $_SERVER['PHP_SELF'] : '').'?'.(isset($_SERVER['QUERY_STRING']) ? $_SERVER['QUERY_STRING'] : ''); + +$page_title = pun_htmlspecialchars($pun_config['o_board_title']).' / Admin / '.$plugin; +require PUN_ROOT.'header.php'; + +// Attempt to load the plugin. We don't use @ here to supress error messages, +// because if we did and a parse error occurred in the plugin, we would only +// get the "blank page of death". +include PUN_ROOT.'plugins/'.$plugin; +if (!defined('PUN_PLUGIN_LOADED')) + message('Loading of the plugin \''.$plugin.'\' failed.'); + +// Output the clearer div +?> +
+ + PUN_ADMIN) + message($lang_common['No permission']); + + +if (isset($_GET['i_per_page']) && isset($_GET['i_start_at'])) +{ + $per_page = intval($_GET['i_per_page']); + $start_at = intval($_GET['i_start_at']); + if ($per_page < 1 || $start_at < 1) + message($lang_common['Bad request']); + + @set_time_limit(0); + + // If this is the first cycle of posts we empty the search index before we proceed + if (isset($_GET['i_empty_index'])) + { + // This is the only potentially "dangerous" thing we can do here, so we check the referer + confirm_referrer('admin_maintenance.php'); + + $truncate_sql = ($db_type != 'sqlite' && $db_type != 'pgsql') ? 'TRUNCATE TABLE ' : 'DELETE FROM '; + $db->query($truncate_sql.$db->prefix.'search_matches') or error('Unable to empty search index match table', __FILE__, __LINE__, $db->error()); + $db->query($truncate_sql.$db->prefix.'search_words') or error('Unable to empty search index words table', __FILE__, __LINE__, $db->error()); + + // Reset the sequence for the search words (not needed for SQLite) + switch ($db_type) + { + case 'mysql': + case 'mysqli': + $result = $db->query('ALTER TABLE '.$db->prefix.'search_words auto_increment=1') or error('Unable to update table auto_increment', __FILE__, __LINE__, $db->error()); + break; + + case 'pgsql'; + $result = $db->query('SELECT setval(\''.$db->prefix.'search_words_id_seq\', 1, false)') or error('Unable to update sequence', __FILE__, __LINE__, $db->error()); + } + } + + $end_at = $start_at + $per_page; + +?> + + + + + +<?php echo pun_htmlspecialchars($pun_config['o_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()); + + $cur_topic = 0; + 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]; + } + + echo 'Processing post '.$cur_post[1].' in topic '.$cur_post[0].'
'."\n"; + + 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()); + + $query_str = ($db->num_rows($result)) ? '?i_per_page='.$per_page.'&i_start_at='.$end_at : ''; + + $db->end_transaction(); + $db->close(); + + exit('
JavaScript redirect unsuccessful. Click here to continue.'); +} + + +// 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 fetch topic info', __FILE__, __LINE__, $db->error()); +if ($db->num_rows($result)) + $first_id = $db->result($result); + +$page_title = pun_htmlspecialchars($pun_config['o_board_title']).' / Admin / Maintenance'; +require PUN_ROOT.'header.php'; + +generate_admin_menu('maintenance'); + +?> +
+

Forum Maintenance

+
+
+
+
+ Rebuild search index +
+

If you've added, edited or removed posts manually in the database or if you're having problems searching, you should rebuild the search index. For best performance you should put the forum in 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. +
Starting Topic ID + + 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 when 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).

+
+
+
+
+
+
+
+
+ + PUN_ADMIN) + message($lang_common['No permission']); + + +if (isset($_POST['form_sent'])) +{ + // Custom referrer check (so we can output a custom error message) + if (!preg_match('#^'.preg_quote(str_replace('www.', '', $pun_config['o_base_url']).'/admin_options.php', '#').'#i', str_replace('www.', '', (isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '')))) + message('Bad HTTP_REFERER. If you have moved these forums from one location to another or switched domains, you need to update the Base URL manually in the database (look for o_base_url in the config table) and then clear the cache by deleting all .php files in the /cache directory.'); + + $form = array_map('trim', $_POST['form']); + + if ($form['board_title'] == '') + message('You must enter a board title.'); + + // Clean default_lang + $form['default_lang'] = preg_replace('#[\.\\\/]#', '', $form['default_lang']); + + require PUN_ROOT.'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 base_url doesn't end with a slash + if (substr($form['base_url'], -1) == '/') + $form['base_url'] = substr($form['base_url'], 0, -1); + + // Clean avatars_dir + $form['avatars_dir'] = str_replace("\0", '', $form['avatars_dir']); + + // Make sure avatars_dir doesn't end with a slash + if (substr($form['avatars_dir'], -1) == '/') + $form['avatars_dir'] = substr($form['avatars_dir'], 0, -1); + + if ($form['additional_navlinks'] != '') + $form['additional_navlinks'] = trim(pun_linebreaks($form['additional_navlinks'])); + + if ($form['announcement_message'] != '') + $form['announcement_message'] = pun_linebreaks($form['announcement_message']); + else + { + $form['announcement_message'] = 'Enter your announcement here.'; + + if ($form['announcement'] == '1') + $form['announcement'] = '0'; + } + + if ($form['rules_message'] != '') + $form['rules_message'] = pun_linebreaks($form['rules_message']); + else + { + $form['rules_message'] = 'Enter your rules here.'; + + if ($form['rules'] == '1') + $form['rules'] = '0'; + } + + if ($form['maintenance_message'] != '') + $form['maintenance_message'] = pun_linebreaks($form['maintenance_message']); + else + { + $form['maintenance_message'] = 'The forums are temporarily down for maintenance. Please try again in a few minutes.\n\n/Administrator'; + + if ($form['maintenance'] == '1') + $form['maintenance'] = '0'; + } + + $form['timeout_visit'] = intval($form['timeout_visit']); + $form['timeout_online'] = intval($form['timeout_online']); + $form['redirect_delay'] = intval($form['redirect_delay']); + $form['topic_review'] = intval($form['topic_review']); + $form['disp_topics_default'] = intval($form['disp_topics_default']); + $form['disp_posts_default'] = intval($form['disp_posts_default']); + $form['indent_num_spaces'] = intval($form['indent_num_spaces']); + $form['avatars_width'] = intval($form['avatars_width']); + $form['avatars_height'] = intval($form['avatars_height']); + $form['avatars_size'] = intval($form['avatars_size']); + + if ($form['timeout_online'] >= $form['timeout_visit']) + message('The value of "Timeout online" must be smaller than the value of "Timeout visit".'); + + while (list($key, $input) = @each($form)) + { + // Only update values that have changed + if (array_key_exists('o_'.$key, $pun_config) && $pun_config['o_'.$key] != $input) + { + if ($input != '' || is_int($input)) + $value = '\''.$db->escape($input).'\''; + else + $value = 'NULL'; + + $db->query('UPDATE '.$db->prefix.'config SET conf_value='.$value.' WHERE conf_name=\'o_'.$db->escape($key).'\'') or error('Unable to update board config', __FILE__, __LINE__, $db->error()); + } + } + + // Regenerate the config cache + require_once PUN_ROOT.'include/cache.php'; + generate_config_cache(); + + redirect('admin_options.php', 'Options updated. Redirecting …'); +} + + +$page_title = pun_htmlspecialchars($pun_config['o_board_title']).' / Admin / Options'; +$form_name = 'update_options'; +require PUN_ROOT.'header.php'; + +generate_admin_menu('options'); + +?> +
+

Options

+
+
+

+
+ +
+ Essentials +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
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. +
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. +
Server timezone + + The timezone of the server where PunBB is installed. +
Default language + + This is the default language style used if the visitor is a guest or a user that hasn't changed from the default in his/her profile. If you remove a language pack, this must be updated. +
Default style + + This is the default style used for guests and users who haven't changed from the default in their profile.
+
+
+
+
+
+ Time and timeouts +
+ + + + + + + + + + + + + + + + + + + + + +
Time format + + [Current format: ] See here for formatting options. +
Date format + + [Current format: ] See here for formatting options. +
Visit timeout + + Number of seconds a user must be idle before his/hers last visit data is updated (primarily affects new message indicators). +
Online timeout + + Number of seconds a user must be idle before being removed from the online users list. +
Redirect time + + Number of seconds to wait when redirecting. If set to 0, no redirect page will be displayed (not recommended). +
+
+
+
+
+
+ Display +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Version number + /> Yes    /> No + Show version number in footer. +
User info in posts + /> Yes    /> No + Show information about the poster under the username in topic view. The information affected is location, register date, post count and the contact links (e-mail and URL). +
User post count + /> Yes    /> No + Show the number of posts a user has made (affects topic view, profile and userlist). +
Smilies + /> Yes    /> No + Convert smilies to small icons. +
Smilies in signatures + /> Yes    /> No + Convert smilies to small icons in user signatures. +
Make clickable links + /> Yes    /> No + When enabled, PunBB will automatically detect any URL's in posts and make them clickable hyperlinks. +
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 + /> Yes    /> No + When enabled, PunBB will add a quick post form at the bottom of topics. This way users can post directly from the topic view. +
Users online + /> Yes    /> No + Display info on the index page about guests and registered users currently browsing the forums. +
Censor words + /> Yes    /> No + Enable this to censor specific words in the forum. See Censoring for more info. +
User ranks + /> Yes    /> No + Enable this to use user ranks. See Ranks for more info. +
User has posted earlier + /> Yes    /> No + 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. +
Quick jump + /> Yes    /> No + Enable the quick jump (jump to forum) drop list. +
GZip output + /> Yes    /> No + 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 one of the Apache modules mod_gzip or mod_deflate set up to compress PHP scripts, you should disable this feature. +
Search all forums + /> Yes    /> No + When disabled, searches will only be allowed in one forum at a time. Disable if server load is high due to excessive searching. +
Additional menu items + + By entering HTML hyperlinks into this textbox, any number of items can be added to the navigation menu at the top of all pages. The format for adding new links is X = <a href="URL">LINK</a> where X is the position at which the link should be inserted (e.g. 0 to insert at the beginning and 2 to insert after "User list"). Separate entries with a linebreak. +
+
+
+
+
+
+ Reports +
+ + + + + + + + + + + + + +
Report method + /> Internal    /> E-mail    /> Both + 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. +
Report new registrations + /> Yes    /> No + If enabled, PunBB will notify users on the mailing list (see below) when a new user registers in the forums. +
Mailing list + + A comma separated list of subscribers. The people on this list are the recipients of reports. +
+
+
+
+
+
+ Avatars +
+ + + + + + + + + + + + + + + + + + + + + +
Use avatars + /> Yes    /> No + When enabled, users will be able to upload an avatar which will be displayed under their title/rank. +
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). +
+
+
+
+
+
+ E-mail +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
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 + /> Yes    /> No + Enable users to subscribe to topics (recieve e-mail when someone replies). +
SMTP server address + + The address of an external SMTP server to send e-mails with. You can specify a custom port number if the SMTP server doesn't run on the default port 25 (example: mail.myhost.com:3580). Leave blank to use the local mail program. +
SMTP username + + Username for SMTP server. Only enter a username if it is required by the SMTP server (most servers do not require authentication). +
SMTP password + + Password for SMTP server. Only enter a password if it is required by the SMTP server (most servers do not require authentication). +
+
+
+
+
+
+ Registration +
+ + + + + + + + + + + + + + + + + +
Allow new registrations + /> Yes    /> No + Controls whether this forum accepts new registrations. Disable only under special circumstances. +
Verify registrations + /> Yes    /> No + 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 verify 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. +
Use forum rules + /> Yes    /> No + When enabled, users must agree to a set of rules when registering (enter text below). The rules will always be available through a link in the navigation table at the top of every page. +
Rules + + 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. +
+
+
+
+
+
+ Announcement +
+ + + + + + + + + +
Display announcement + /> Yes    /> No + Enable this to display the below message in the forums. +
Announcement message + + This text will not be parsed like regular posts and thus may contain HTML. +
+
+
+
+
+
+ Maintenance +
+ + + + + + + + + +
Maintenance mode + /> Yes    /> No + 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. +
Maintenance 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. +
+
+
+
+

+
+
+
+
+ + PUN_ADMIN) + message($lang_common['No permission']); + + +if (isset($_POST['form_sent'])) +{ + confirm_referrer('admin_permissions.php'); + + $form = array_map('intval', $_POST['form']); + + while (list($key, $input) = @each($form)) + { + // Only update values that have changed + if (array_key_exists('p_'.$key, $pun_config) && $pun_config['p_'.$key] != $input) + $db->query('UPDATE '.$db->prefix.'config SET conf_value='.$input.' WHERE conf_name=\'p_'.$db->escape($key).'\'') or error('Unable to update board config', __FILE__, __LINE__, $db->error()); + } + + // Regenerate the config cache + require_once PUN_ROOT.'include/cache.php'; + generate_config_cache(); + + redirect('admin_permissions.php', 'Permissions updated. Redirecting …'); +} + + +$page_title = pun_htmlspecialchars($pun_config['o_board_title']).' / Admin / Permissions'; +require PUN_ROOT.'header.php'; +generate_admin_menu('permissions'); + +?> +
+

Permissions

+
+
+

+
+ +
+ Posting +
+ + + + + + + + + + + + + + + + + + + + + +
BBCode + /> Yes    /> No + Allow BBCode in posts (recommended). +
Image tag + /> Yes    /> No + Allow the BBCode [img][/img] tag in posts. +
All caps message + /> Yes    /> No + Allow a message to contain only capital letters. +
All caps subject + /> Yes    /> No + Allow a subject to contain only capital letters. +
Require guest e-mail + /> Yes    /> No + Require guests to supply an e-mail address when posting. +
+
+
+
+
+
+ Signatures +
+ + + + + + + + + + + + + + + + + + + + + +
BBCodes in signatures + /> Yes    /> No + Allow BBCodes in user signatures. +
Image tag in signatures + /> Yes    /> No + Allow the BBCode [img][/img] tag in user signatures (not recommended). +
All caps signature + /> Yes    /> No + Allow a signature to contain only capital letters. +
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. +
+
+
+
+
+
+ Moderators +
+ + + + + + + + + + + + + + + + + +
Edit user profiles + /> Yes    /> No + Allow moderators to edit user profiles. +
Rename users + /> Yes    /> No + Allow moderators to rename users. Other moderators and administrators are excluded. +
Change user passwords + /> Yes    /> No + Allow moderators to change user passwords. Other moderators and administrators are excluded. +
Ban users + /> Yes    /> No + Allow moderators to ban users (and edit/remove current bans). +
+
+
+
+
+
+ Registration +
+ + + + + + + + + +
Allow banned e-mail addresses + /> Yes    /> No + 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). +
Allow duplicate e-mail addresses + /> Yes    /> No + 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. +
+
+
+
+

+
+
+
+
+ + PUN_ADMIN) + message($lang_common['No permission']); + + +if (isset($_GET['action']) || isset($_POST['prune']) || isset($_POST['prune_comply'])) +{ + if (isset($_POST['prune_comply'])) + { + confirm_referrer('admin_prune.php'); + + $prune_from = $_POST['prune_from']; + $prune_days = intval($_POST['prune_days']); + $prune_date = ($prune_days) ? 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); + update_forum($fid); + } + } + else + { + $prune_from = intval($prune_from); + prune($prune_from, $_POST['prune_sticky'], $prune_date); + update_forum($prune_from); + } + + // Locate any "orphaned redirect topics" and delete them + $result = $db->query('SELECT t1.id FROM '.$db->prefix.'topics AS t1 LEFT JOIN '.$db->prefix.'topics AS t2 ON t1.moved_to=t2.id WHERE t2.id IS NULL AND t1.moved_to IS NOT NULL') or error('Unable to fetch redirect topics', __FILE__, __LINE__, $db->error()); + $num_orphans = $db->num_rows($result); + + if ($num_orphans) + { + for ($i = 0; $i < $num_orphans; ++$i) + $orphans[] = $db->result($result, $i); + + $db->query('DELETE FROM '.$db->prefix.'topics WHERE id IN('.implode(',', $orphans).')') or error('Unable to delete redirect topics', __FILE__, __LINE__, $db->error()); + } + + redirect('admin_prune.php', 'Posts pruned. Redirecting …'); + } + + + $prune_days = $_POST['req_prune_days']; + if (!@preg_match('#^\d+$#', $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.' AND moved_to IS NULL'; + + if ($_POST['prune_sticky'] == '0') + $sql .= ' AND sticky=\'0\''; + + if ($prune_from != 'all') + { + $prune_from = intval($prune_from); + $sql .= ' AND forum_id='.$prune_from; + + // Fetch the forum name (just for cosmetic reasons) + $result = $db->query('SELECT forum_name FROM '.$db->prefix.'forums WHERE id='.$prune_from) or error('Unable to fetch forum name', __FILE__, __LINE__, $db->error()); + $forum = '"'.pun_htmlspecialchars($db->result($result)).'"'; + } + else + $forum = 'all forums'; + + $result = $db->query($sql) or error('Unable to fetch topic prune count', __FILE__, __LINE__, $db->error()); + $num_topics = $db->result($result); + + if (!$num_topics) + message('There are no topics that are '.$prune_days.' days old. Please decrease the value of "Days old" and try again.'); + + + $page_title = pun_htmlspecialchars($pun_config['o_board_title']).' / Admin / Prune'; + require PUN_ROOT.'header.php'; + + generate_admin_menu('prune'); + +?> +
+

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

+
+
+
+
+ + 'Days old'); + $focus_element = array('prune', 'req_prune_days'); + require PUN_ROOT.'header.php'; + + generate_admin_menu('prune'); + +?> +
+

Prune

+
+
+
+ +
+ Prune old posts +
+ + + + + + + + + + + + + +
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 dated less than 30 days old would be deleted. +
Prune sticky topics +  Yes    No + When enabled sticky topics will also be pruned. +
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.

+
+
+
+
+
+
+
+
+ + PUN_ADMIN) + message($lang_common['No permission']); + + +// Add a rank +if (isset($_POST['add_rank'])) +{ + confirm_referrer('admin_ranks.php'); + + $rank = trim($_POST['new_rank']); + $min_posts = $_POST['new_min_posts']; + + if ($rank == '') + message('You must enter a rank title.'); + + if (!@preg_match('#^\d+$#', $min_posts)) + message('Minimum posts must be a positive integer value.'); + + // Make sure there isn't already a rank with the same min_posts value + $result = $db->query('SELECT 1 FROM '.$db->prefix.'ranks WHERE min_posts='.$min_posts) or error('Unable to fetch rank info', __FILE__, __LINE__, $db->error()); + if ($db->num_rows($result)) + message('There is already a rank with a minimun posts value of '.$min_posts.'.'); + + $db->query('INSERT INTO '.$db->prefix.'ranks (rank, min_posts) VALUES(\''.$db->escape($rank).'\', '.$min_posts.')') or error('Unable to add rank', __FILE__, __LINE__, $db->error()); + + // Regenerate the ranks cache + require_once PUN_ROOT.'include/cache.php'; + generate_ranks_cache(); + + redirect('admin_ranks.php', 'Rank added. Redirecting …'); +} + + +// Update a rank +else if (isset($_POST['update'])) +{ + confirm_referrer('admin_ranks.php'); + + $id = intval(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 (!@preg_match('#^\d+$#', $min_posts)) + message('Minimum posts must be a positive integer value.'); + + // Make sure there isn't already a rank with the same min_posts value + $result = $db->query('SELECT 1 FROM '.$db->prefix.'ranks WHERE id!='.$id.' AND min_posts='.$min_posts) or error('Unable to fetch rank info', __FILE__, __LINE__, $db->error()); + if ($db->num_rows($result)) + message('There is already a rank with a minimun posts value of '.$min_posts.'.'); + + $db->query('UPDATE '.$db->prefix.'ranks SET rank=\''.$db->escape($rank).'\', min_posts='.$min_posts.' WHERE id='.$id) or error('Unable to update rank', __FILE__, __LINE__, $db->error()); + + // Regenerate the ranks cache + require_once PUN_ROOT.'include/cache.php'; + generate_ranks_cache(); + + redirect('admin_ranks.php', 'Rank updated. Redirecting …'); +} + + +// Remove a rank +else if (isset($_POST['remove'])) +{ + confirm_referrer('admin_ranks.php'); + + $id = intval(key($_POST['remove'])); + + $db->query('DELETE FROM '.$db->prefix.'ranks WHERE id='.$id) or error('Unable to delete rank', __FILE__, __LINE__, $db->error()); + + // Regenerate the ranks cache + require_once PUN_ROOT.'include/cache.php'; + generate_ranks_cache(); + + redirect('admin_ranks.php', 'Rank removed. Redirecting …'); +} + + +$page_title = pun_htmlspecialchars($pun_config['o_board_title']).' / Admin / Ranks'; +$focus_element = array('ranks', 'new_rank'); +require PUN_ROOT.'header.php'; + +generate_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 titleMinimum postsAction
+
+
+
+
+
+ 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)) +{ + +?> + + + + + + + + + +fetch_assoc($result)) + echo "\t\t\t\t\t\t\t\t".''."\n"; + +?> + +
Rank titleMinimum PostsActions
 
+No ranks in list.

'."\n"; + +?> +
+
+
+
+
+
+
+ + PUN_MOD) + message($lang_common['No permission']); + + +// Zap a report +if (isset($_POST['zap_id'])) +{ + confirm_referrer('admin_reports.php'); + + $zap_id = intval(key($_POST['zap_id'])); + + $result = $db->query('SELECT zapped FROM '.$db->prefix.'reports WHERE id='.$zap_id) or error('Unable to fetch report info', __FILE__, __LINE__, $db->error()); + $zapped = $db->result($result); + + if ($zapped == '') + $db->query('UPDATE '.$db->prefix.'reports SET zapped='.time().', zapped_by='.$pun_user['id'].' WHERE id='.$zap_id) or error('Unable to zap report', __FILE__, __LINE__, $db->error()); + + redirect('admin_reports.php', 'Report zapped. Redirecting …'); +} + + +$page_title = pun_htmlspecialchars($pun_config['o_board_title']).' / Admin / Reports'; +require PUN_ROOT.'header.php'; + +generate_admin_menu('reports'); + +?> +
+

New 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 LEFT JOIN '.$db->prefix.'topics AS t ON r.topic_id=t.id LEFT JOIN '.$db->prefix.'forums AS f ON r.forum_id=f.id LEFT JOIN '.$db->prefix.'users AS u ON r.reported_by=u.id WHERE r.zapped IS NULL ORDER BY created DESC') or error('Unable to fetch report list', __FILE__, __LINE__, $db->error()); + +if ($db->num_rows($result)) +{ + while ($cur_report = $db->fetch_assoc($result)) + { + $reporter = ($cur_report['reporter'] != '') ? ''.pun_htmlspecialchars($cur_report['reporter']).'' : 'Deleted user'; + $forum = ($cur_report['forum_name'] != '') ? ''.pun_htmlspecialchars($cur_report['forum_name']).'' : 'Deleted'; + $topic = ($cur_report['subject'] != '') ? ''.pun_htmlspecialchars($cur_report['subject']).'' : 'Deleted'; + $post = ($cur_report['post_id'] != '') ? str_replace("\n", '
', pun_htmlspecialchars($cur_report['message'])) : 'Deleted'; + $postid = ($cur_report['post_id'] != '') ? 'Post #'.$cur_report['post_id'].'' : 'Deleted'; + +?> +
+
+ Reported +
+ + + + + + + + + +
Forum » Topic » Post »  » 
Report by
+
+
+
+There are no new reports.

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

10 last zapped 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 LEFT JOIN '.$db->prefix.'topics AS t ON r.topic_id=t.id LEFT JOIN '.$db->prefix.'forums AS f ON r.forum_id=f.id LEFT JOIN '.$db->prefix.'users AS u ON r.reported_by=u.id LEFT JOIN '.$db->prefix.'users AS u2 ON r.zapped_by=u2.id WHERE r.zapped IS NOT NULL ORDER BY zapped DESC LIMIT 10') or error('Unable to fetch report list', __FILE__, __LINE__, $db->error()); + +if ($db->num_rows($result)) +{ + while ($cur_report = $db->fetch_assoc($result)) + { + $reporter = ($cur_report['reporter'] != '') ? ''.pun_htmlspecialchars($cur_report['reporter']).'' : 'Deleted user'; + $forum = ($cur_report['forum_name'] != '') ? ''.pun_htmlspecialchars($cur_report['forum_name']).'' : 'Deleted'; + $topic = ($cur_report['subject'] != '') ? ''.pun_htmlspecialchars($cur_report['subject']).'' : 'Deleted'; + $post = ($cur_report['post_id'] != '') ? str_replace("\n", '
', pun_htmlspecialchars($cur_report['message'])) : 'Post deleted'; + $post_id = ($cur_report['post_id'] != '') ? 'Post #'.$cur_report['post_id'].'' : 'Deleted'; + $zapped_by = ($cur_report['zapped_by'] != '') ? ''.pun_htmlspecialchars($cur_report['zapped_by']).'' : 'N/A'; + +?> +
+
+ Zapped +
+ + + + + + + + + +
Forum » Topic » Post »  » 
Reported by
Zapped by
+
+
+
+There are no zapped reports.

'."\n"; + +?> +
+
+
+
+ + PUN_MOD) + message($lang_common['No permission']); + + +// Show IP statistics for a certain user ID +if (isset($_GET['ip_stats'])) +{ + $ip_stats = intval($_GET['ip_stats']); + if ($ip_stats < 1) + message($lang_common['Bad request']); + + + $page_title = pun_htmlspecialchars($pun_config['o_board_title']).' / Admin / Users'; + require PUN_ROOT.'header.php'; + +?> +
+
+ +
+
+ +
+

Users

+
+
+ + + + + + + + + + +query('SELECT poster_ip, MAX(posted) AS last_used, COUNT(id) AS used_times FROM '.$db->prefix.'posts WHERE poster_id='.$ip_stats.' GROUP BY poster_ip ORDER BY last_used DESC') or error('Unable to fetch post info', __FILE__, __LINE__, $db->error()); + if ($db->num_rows($result)) + { + while ($cur_ip = $db->fetch_assoc($result)) + { + +?> + + + + + + +'."\n"; + +?> + +
IP addressLast usedTimes foundAction
Find more users for this ip
There are currently no posts by that user in the forum.
+
+
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+

Users

+
+
+ + + + + + + + + + + + +query('SELECT DISTINCT poster_id, poster FROM '.$db->prefix.'posts WHERE poster_ip=\''.$db->escape($ip).'\' ORDER BY poster DESC') or error('Unable to fetch post info', __FILE__, __LINE__, $db->error()); + $num_posts = $db->num_rows($result); + + if ($num_posts) + { + // Loop through users and print out some info + for ($i = 0; $i < $num_posts; ++$i) + { + list($poster_id, $poster) = $db->fetch_row($result); + + $result2 = $db->query('SELECT u.id, u.username, u.email, u.title, u.num_posts, u.admin_note, g.g_id, g.g_user_title FROM '.$db->prefix.'users AS u INNER JOIN '.$db->prefix.'groups AS g ON g.g_id=u.group_id WHERE u.id>1 AND u.id='.$poster_id) or error('Unable to fetch user info', __FILE__, __LINE__, $db->error()); + + if (($user_data = $db->fetch_assoc($result2))) + { + $user_title = get_title($user_data); + + $actions = 'View IP stats - Show posts'; + +?> + + + + + + + + + + + + + + + + + +'."\n"; + +?> + +
UsernameE-mailTitle/StatusPostsAdmin noteActions
'.pun_htmlspecialchars($user_data['username']).'' ?>
 Guest   
The supplied IP address could not be found in the database.
+
+
+
+ +
+
+ +
+
+'.$last_post_after; + if ($last_post_before != '') + $conditions[] = 'u.last_post<'.$last_post_before; + if ($registered_after != '') + $conditions[] = 'u.registered>'.$registered_after; + if ($registered_before != '') + $conditions[] = 'u.registered<'.$registered_before; + + $like_command = ($db_type == 'pgsql') ? 'ILIKE' : 'LIKE'; + while (list($key, $input) = @each($form)) + { + if ($input != '' && in_array($key, array('username', 'email', 'title', 'realname', 'url', 'jabber', 'icq', 'msn', 'aim', 'yahoo', 'location', 'signature', 'admin_note'))) + $conditions[] = 'u.'.$db->escape($key).' '.$like_command.' \''.$db->escape(str_replace('*', '%', $input)).'\''; + } + + if ($posts_greater != '') + $conditions[] = 'u.num_posts>'.$posts_greater; + if ($posts_less != '') + $conditions[] = 'u.num_posts<'.$posts_less; + + if ($user_group != 'all') + $conditions[] = 'u.group_id='.intval($user_group); + + if (empty($conditions)) + message('You didn\'t enter any search terms.'); + + + $page_title = pun_htmlspecialchars($pun_config['o_board_title']).' / Admin / Users'; + require PUN_ROOT.'header.php'; + +?> +
+
+ +
+
+ +
+

Users

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

User search

+
+
+

+
+
+ Enter search criteria +
+

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
MSN Messenger
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

+
+
+
+
+ Enter IP to search for +
+ + + + + +
IP address
+ The IP address to search for in the post database.
+
+
+
+
+
+
+
+ + +Order Allow,Deny +Deny from All + \ No newline at end of file diff -r 000000000000 -r f9ffdbd96607 punbb/cache/index.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/punbb/cache/index.html Wed Jul 11 21:01:48 2007 -0400 @@ -0,0 +1,8 @@ + + +. + + +. + + \ No newline at end of file diff -r 000000000000 -r f9ffdbd96607 punbb/delete.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/punbb/delete.php Wed Jul 11 21:01:48 2007 -0400 @@ -0,0 +1,127 @@ +query('SELECT f.id AS fid, f.forum_name, f.moderators, f.redirect_url, fp.post_replies, fp.post_topics, t.id AS tid, t.subject, t.posted, t.closed, p.poster, p.poster_id, p.message, p.hide_smilies FROM '.$db->prefix.'posts AS p INNER JOIN '.$db->prefix.'topics AS t ON t.id=p.topic_id INNER JOIN '.$db->prefix.'forums AS f ON f.id=t.forum_id LEFT JOIN '.$db->prefix.'forum_perms AS fp ON (fp.forum_id=f.id AND fp.group_id='.$pun_user['g_id'].') WHERE (fp.read_forum IS NULL OR fp.read_forum=1) AND p.id='.$id) or error('Unable to fetch post info', __FILE__, __LINE__, $db->error()); +if (!$db->num_rows($result)) + message($lang_common['Bad request']); + +$cur_post = $db->fetch_assoc($result); + +// Sort out who the moderators are and if we are currently a moderator (or an admin) +$mods_array = ($cur_post['moderators'] != '') ? unserialize($cur_post['moderators']) : array(); +$is_admmod = ($pun_user['g_id'] == PUN_ADMIN || ($pun_user['g_id'] == PUN_MOD && array_key_exists($pun_user['username'], $mods_array))) ? true : false; + +// Determine whether this post is the "topic post" or not +$result = $db->query('SELECT id FROM '.$db->prefix.'posts WHERE topic_id='.$cur_post['tid'].' ORDER BY posted LIMIT 1') or error('Unable to fetch post info', __FILE__, __LINE__, $db->error()); +$topic_post_id = $db->result($result); + +$is_topic_post = ($id == $topic_post_id) ? true : false; + +// Do we have permission to edit this post? +if (($pun_user['g_delete_posts'] == '0' || + ($pun_user['g_delete_topics'] == '0' && $is_topic_post) || + $cur_post['poster_id'] != $pun_user['id'] || + $cur_post['closed'] == '1') && + !$is_admmod) + message($lang_common['No permission']); + +// Load the delete.php language file +require PUN_ROOT.'lang/'.$pun_user['language'].'/delete.php'; + + +if (isset($_POST['delete'])) +{ + if ($is_admmod) + confirm_referrer('delete.php'); + + require PUN_ROOT.'include/search_idx.php'; + + if ($is_topic_post) + { + // Delete the topic and all of it's posts + delete_topic($cur_post['tid']); + update_forum($cur_post['fid']); + + redirect('viewforum.php?id='.$cur_post['fid'], $lang_delete['Topic del redirect']); + } + else + { + // Delete just this one post + delete_post($id, $cur_post['tid']); + update_forum($cur_post['fid']); + + redirect('viewtopic.php?id='.$cur_post['tid'], $lang_delete['Post del redirect']); + } +} + + +$page_title = pun_htmlspecialchars($pun_config['o_board_title']).' / '.$lang_delete['Delete post']; +require PUN_ROOT.'header.php'; + +require PUN_ROOT.'include/parser.php'; +$cur_post['message'] = parse_message($cur_post['message'], $cur_post['hide_smilies']); + +?> +
+
+
  •  » 
  •  » 
+
+
+ +
+

+
+
+
+
+ +
+
+

:

+ +
+
+
+
+

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

+
+

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

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

+
+
+
+
+ + +
+ + + +
+
+ '.$lang_post['Hide smilies']; + else + $checkboxes[] = '
+
+
+ +
+
+ '."\n\t\t\t\t\t\t\t", $checkboxes).''."\n" ?> +
+
+
+ +
+

+
+
+
+ + + Show board statistics: + + + And finally some examples using extern.php to output an RSS 0.91 + feed. + + Output the 15 most recently active topics: + http://host.com/extern.php?action=active&type=RSS + + Output the 15 newest topics from forum with ID=2: + http://host.com/extern.php?action=active&type=RSS&fid=2 + + Below you will find some variables you can edit to tailor the + scripts behaviour to your needs. + + +/***********************************************************************/ + +// The maximum number of topics that will be displayed +$show_max_topics = 60; + +// The length at which topic subjects will be truncated (for HTML output) +$max_subject_length = 30; + +/***********************************************************************/ + +// DO NOT EDIT ANYTHING BELOW THIS LINE! (unless you know what you are doing) + + +define('PUN_ROOT', './'); +@include PUN_ROOT.'config.php'; + +// If PUN isn't defined, config.php is missing or corrupt +if (!defined('PUN')) + exit('The file \'config.php\' doesn\'t exist or is corrupt. Please run install.php to install PunBB first.'); + + +// Make sure PHP reports all errors except E_NOTICE +error_reporting(E_ALL ^ E_NOTICE); + +// Turn off magic_quotes_runtime +set_magic_quotes_runtime(0); + + +// Load the functions script +require PUN_ROOT.'include/functions.php'; + +// Load DB abstraction layer and try to connect +require PUN_ROOT.'include/dblayer/common_db.php'; + +// Load cached config +@include PUN_ROOT.'cache/cache_config.php'; +if (!defined('PUN_CONFIG_LOADED')) +{ + require PUN_ROOT.'include/cache.php'; + generate_config_cache(); + require PUN_ROOT.'cache/cache_config.php'; +} + +// Make sure we (guests) have permission to read the forums +$result = $db->query('SELECT g_read_board FROM '.$db->prefix.'groups WHERE g_id=3') or error('Unable to fetch group info', __FILE__, __LINE__, $db->error()); +if ($db->result($result) == '0') + exit('No permission'); + + +// Attempt to load the common language file +@include PUN_ROOT.'lang/'.$pun_config['o_default_lang'].'/common.php'; +if (!isset($lang_common)) + exit('There is no valid language pack \''.$pun_config['o_default_lang'].'\' installed. Please reinstall a language of that name.'); + +// Check if we are to display a maintenance message +if ($pun_config['o_maintenance'] && !defined('PUN_TURN_OFF_MAINT')) + maintenance_message(); + +if (!isset($_GET['action'])) + exit('No parameters supplied. See extern.php for instructions.'); + + +// +// Converts the CDATA end sequence ]]> into ]]> +// +function escape_cdata($str) +{ + return str_replace(']]>', ']]>', $str); +} + + +// +// Show recent discussions +// +if ($_GET['action'] == 'active' || $_GET['action'] == 'new') +{ + $order_by = ($_GET['action'] == 'active') ? 't.last_post' : 't.posted'; + $forum_sql = ''; + + // Was any specific forum ID's supplied? + if (isset($_GET['fid']) && $_GET['fid'] != '') + { + $fids = explode(',', trim($_GET['fid'])); + $fids = array_map('intval', $fids); + + if (!empty($fids)) + $forum_sql = ' AND f.id IN('.implode(',', $fids).')'; + } + + // Any forum ID's to exclude? + if (isset($_GET['nfid']) && $_GET['nfid'] != '') + { + $nfids = explode(',', trim($_GET['nfid'])); + $nfids = array_map('intval', $nfids); + + if (!empty($nfids)) + $forum_sql = ' AND f.id NOT IN('.implode(',', $nfids).')'; + } + + // Should we output this as RSS? + if (isset($_GET['type']) && strtoupper($_GET['type']) == 'RSS') + { + $rss_description = ($_GET['action'] == 'active') ? $lang_common['RSS Desc Active'] : $lang_common['RSS Desc New']; + $url_action = ($_GET['action'] == 'active') ? '&action=new' : ''; + + // Send XML/no cache headers + header('Content-Type: text/xml'); + header('Expires: '.gmdate('D, d M Y H:i:s').' GMT'); + header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); + header('Pragma: public'); + + // It's time for some syndication! + echo ''."\r\n"; + echo ''."\r\n"; + echo ''."\r\n"; + echo ''."\r\n"; + echo "\t".''.pun_htmlspecialchars($pun_config['o_board_title']).''."\r\n"; + echo "\t".''.$pun_config['o_base_url'].'/'."\r\n"; + echo "\t".''.pun_htmlspecialchars($rss_description.' '.$pun_config['o_board_title']).''."\r\n"; + echo "\t".'en-us'."\r\n"; + + // Fetch 15 topics + $result = $db->query('SELECT t.id, t.poster, t.subject, t.posted, t.last_post, f.id AS fid, f.forum_name FROM '.$db->prefix.'topics AS t INNER JOIN '.$db->prefix.'forums AS f ON f.id=t.forum_id LEFT JOIN '.$db->prefix.'forum_perms AS fp ON (fp.forum_id=f.id AND fp.group_id=3) WHERE (fp.read_forum IS NULL OR fp.read_forum=1) AND t.moved_to IS NULL'.$forum_sql.' ORDER BY '.$order_by.' DESC LIMIT 15') or error('Unable to fetch topic list', __FILE__, __LINE__, $db->error()); + + while ($cur_topic = $db->fetch_assoc($result)) + { + if ($pun_config['o_censoring'] == '1') + $cur_topic['subject'] = censor_words($cur_topic['subject']); + + echo "\t".''."\r\n"; + echo "\t\t".''.pun_htmlspecialchars($cur_topic['subject']).''."\r\n"; + echo "\t\t".''.$pun_config['o_base_url'].'/viewtopic.php?id='.$cur_topic['id'].$url_action.''."\r\n"; + echo "\t\t".''.$cur_topic['forum_name'].'
'."\r\n".$lang_common['Author'].': '.$cur_topic['poster'].'
'."\r\n".$lang_common['Posted'].': '.date('r', $cur_topic['posted']).'
'."\r\n".$lang_common['Last post'].': '.date('r', $cur_topic['last_post'])).']]>
'."\r\n"; + echo "\t".'
'."\r\n"; + } + + echo '
'."\r\n"; + echo '
'; + } + + + // Output regular HTML + else + { + $show = isset($_GET['show']) ? intval($_GET['show']) : 15; + if ($show < 1 || $show > 50) + $show = 15; + + // Fetch $show topics + $result = $db->query('SELECT t.id, t.subject FROM '.$db->prefix.'topics AS t INNER JOIN '.$db->prefix.'forums AS f ON f.id=t.forum_id LEFT JOIN '.$db->prefix.'forum_perms AS fp ON (fp.forum_id=f.id AND fp.group_id=3) WHERE (fp.read_forum IS NULL OR fp.read_forum=1) AND t.moved_to IS NULL'.$forum_sql.' ORDER BY '.$order_by.' DESC LIMIT '.$show) or error('Unable to fetch topic list', __FILE__, __LINE__, $db->error()); + + while ($cur_topic = $db->fetch_assoc($result)) + { + if ($pun_config['o_censoring'] == '1') + $cur_topic['subject'] = censor_words($cur_topic['subject']); + + if (pun_strlen($cur_topic['subject']) > $max_subject_length) + $subject_truncated = pun_htmlspecialchars(trim(substr($cur_topic['subject'], 0, ($max_subject_length-5)))).' …'; + else + $subject_truncated = pun_htmlspecialchars($cur_topic['subject']); + + echo '
  • '.$subject_truncated.'
  • '."\n"; + } + } + + return; +} + + +// +// Show users online +// +else if ($_GET['action'] == 'online' || $_GET['action'] == 'online_full') +{ + // Load the index.php language file + require PUN_ROOT.'lang/'.$pun_config['o_default_lang'].'/index.php'; + + // Fetch users online info and generate strings for output + $num_guests = $num_users = 0; + $users = array(); + $result = $db->query('SELECT user_id, ident FROM '.$db->prefix.'online WHERE idle=0 ORDER BY ident', true) or error('Unable to fetch online list', __FILE__, __LINE__, $db->error()); + + while ($pun_user_online = $db->fetch_assoc($result)) + { + if ($pun_user_online['user_id'] > 1) + { + $users[] = ''.pun_htmlspecialchars($pun_user_online['ident']).''; + ++$num_users; + } + else + ++$num_guests; + } + + echo $lang_index['Guests online'].': '.$num_guests.'
    '; + + if ($_GET['action'] == 'online_full') + echo $lang_index['Users online'].': '.implode(', ', $users).'
    '; + else + echo $lang_index['Users online'].': '.$num_users.'
    '; + + return; +} + + +// +// Show board statistics +// +else if ($_GET['action'] == 'stats') +{ + // Load the index.php language file + require PUN_ROOT.'lang/'.$pun_config['o_default_lang'].'/index.php'; + + // Collect some statistics from the database + $result = $db->query('SELECT COUNT(id)-1 FROM '.$db->prefix.'users') or error('Unable to fetch total user count', __FILE__, __LINE__, $db->error()); + $stats['total_users'] = $db->result($result); + + $result = $db->query('SELECT id, username FROM '.$db->prefix.'users ORDER BY registered DESC LIMIT 1') or error('Unable to fetch newest registered user', __FILE__, __LINE__, $db->error()); + $stats['last_user'] = $db->fetch_assoc($result); + + $result = $db->query('SELECT SUM(num_topics), SUM(num_posts) FROM '.$db->prefix.'forums') or error('Unable to fetch topic/post count', __FILE__, __LINE__, $db->error()); + list($stats['total_topics'], $stats['total_posts']) = $db->fetch_row($result); + + echo $lang_index['No of users'].': '.$stats['total_users'].'
    '; + echo $lang_index['Newest user'].': '.pun_htmlspecialchars($stats['last_user']['username']).'
    '; + echo $lang_index['No of topics'].': '.$stats['total_topics'].'
    '; + echo $lang_index['No of posts'].': '.$stats['total_posts']; + + return; +} + + +else + exit('Bad request'); diff -r 000000000000 -r f9ffdbd96607 punbb/footer.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/punbb/footer.php Wed Jul 11 21:01:48 2007 -0400 @@ -0,0 +1,146 @@ +', $tpl_temp, $tpl_main); +ob_end_clean(); +// END SUBST - + + +// START SUBST - +ob_start(); + +?> +
    +

    +
    +
    +'."\n\t\t\t\t".'
    '.$lang_common['Search links'].'
    '."\n\t\t\t\t".'
    '.$lang_common['Show recent posts'].'
    '."\n"; + echo "\t\t\t\t".'
    '.$lang_common['Show unanswered posts'].'
    '."\n"; + + if ($pun_config['o_subscriptions'] == '1') + echo "\t\t\t\t".'
    '.$lang_common['Show subscriptions'].'
    '."\n"; + + echo "\t\t\t\t".'
    '.$lang_common['Show your posts'].'
    '."\n\t\t\t".''."\n"; + } + else + { + if ($pun_user['g_search'] == '1') + { + echo "\n\t\t\t".''."\n"; + } + } +} +else if ($footer_style == 'viewforum' || $footer_style == 'viewtopic') +{ + echo "\n\t\t\t".'
    '."\n"; + + // Display the "Jump to" drop list + if ($pun_config['o_quickjump'] == '1') + { + // Load cached quickjump + @include PUN_ROOT.'cache/cache_quickjump_'.$pun_user['g_id'].'.php'; + if (!defined('PUN_QJ_LOADED')) + { + require_once PUN_ROOT.'include/cache.php'; + generate_quickjump_cache($pun_user['g_id']); + require PUN_ROOT.'cache/cache_quickjump_'.$pun_user['g_id'].'.php'; + } + } + + if ($footer_style == 'viewforum' && $is_admmod) + echo "\t\t\t".'

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

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

    Powered by PunBB
    © Copyright 2002–2005 Rickard Andersson

    +[ Generated in '.$time_diff.' seconds, '.$db->get_num_queries().' queries executed ]

    '."\n"; +} + +?> +
    +
    +
    +
    +end_transaction(); + +// Display executed queries (if enabled) +if (defined('PUN_SHOW_QUERIES')) + display_saved_queries(); + +$tpl_temp = trim(ob_get_contents()); +$tpl_main = str_replace('', $tpl_temp, $tpl_main); +ob_end_clean(); +// END SUBST - + + +// Close the db connection (and free up any result data) +$db->close(); + +// Spit out the page +exit($tpl_main); diff -r 000000000000 -r f9ffdbd96607 punbb/header.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/punbb/header.php Wed Jul 11 21:01:48 2007 -0400 @@ -0,0 +1,225 @@ + +while (preg_match('##', $tpl_main, $cur_include)) +{ + if (!file_exists(PUN_ROOT.'include/user/'.$cur_include[1].'.'.$cur_include[2])) + error('Unable to process user include '.htmlspecialchars($cur_include[0]).' from template main.tpl. There is no such file in folder /include/user/'); + + ob_start(); + include PUN_ROOT.'include/user/'.$cur_include[1].'.'.$cur_include[2]; + $tpl_temp = ob_get_contents(); + $tpl_main = str_replace($cur_include[0], $tpl_temp, $tpl_main); + ob_end_clean(); +} +// END SUBST - + + +// START SUBST - +$tpl_main = str_replace('', $lang_common['lang_direction'], $tpl_main); +// END SUBST - + + +// START SUBST - +$tpl_main = str_replace('', $lang_common['lang_encoding'], $tpl_main); +// END SUBST - + + +// START SUBST - +ob_start(); + +// Is this a page that we want search index spiders to index? +if (!defined('PUN_ALLOW_INDEX')) + echo ''."\n"; + +?> +<?php echo $page_title ?> + +'."\n"; + +if (isset($required_fields)) +{ + // Output JavaScript to validate form (make sure required fields are filled out) + +?> + +'; + +$tpl_temp = trim(ob_get_contents()); +$tpl_main = str_replace('', $tpl_temp, $tpl_main); +ob_end_clean(); +// END SUBST - + + +// START SUBST - +if (isset($focus_element)) +{ + $tpl_main = str_replace('', '', $tpl_main); +} +// END SUBST - + + +// START SUBST - +$tpl_main = str_replace('', htmlspecialchars(basename($_SERVER['PHP_SELF'], '.php')), $tpl_main); +// END SUBST - + + +// START SUBST - +$tpl_main = str_replace('', '

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

    ', $tpl_main); +// END SUBST - + + +// START SUBST - +$tpl_main = str_replace('', '

    '.$pun_config['o_board_desc'].'

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

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

    '."\n\t\t".'
    '; +else +{ + $tpl_temp = '
    '."\n\t\t\t".'
      '."\n\t\t\t\t".'
    • '.$lang_common['Logged in as'].' '.pun_htmlspecialchars($pun_user['username']).'
    • '."\n\t\t\t\t".'
    • '.$lang_common['Last visit'].': '.format_time($pun_user['last_visit']).'
    • '; + + if ($pun_user['g_id'] < PUN_GUEST) + { + $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)) + $tpl_temp .= "\n\t\t\t\t".''; + + if ($pun_config['o_maintenance'] == '1') + $tpl_temp .= "\n\t\t\t\t".''; + } + + if (in_array(basename($_SERVER['PHP_SELF']), array('index.php', 'search.php'))) + $tpl_temp .= "\n\t\t\t".'
    '."\n\t\t\t".''."\n\t\t\t".'
    '."\n\t\t".'
    '; + else + $tpl_temp .= "\n\t\t\t".''."\n\t\t\t".'
    '."\n\t\t".''; +} + +$tpl_main = str_replace('', $tpl_temp, $tpl_main); +// END SUBST - + + +// START SUBST - +if ($pun_config['o_announcement'] == '1') +{ + ob_start(); + +?> +
    +

    +
    +
    +
    +
    +
    +
    +', $tpl_temp, $tpl_main); + ob_end_clean(); +} +else + $tpl_main = str_replace('', '', $tpl_main); +// END SUBST - + + +// START SUBST - +ob_start(); + + +define('PUN_HEADER', 1); diff -r 000000000000 -r f9ffdbd96607 punbb/help.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/punbb/help.php Wed Jul 11 21:01:48 2007 -0400 @@ -0,0 +1,157 @@ + +

    +
    +
    +


    +

    +
    +
    +

    +
    +


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

    +
    +


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

    +
    +

    +
    [img]http://www.punbb.org/img/small_logo.png[/img] http://www.punbb.org/img/small_logo.png
    +
    +

    +
    +
    +

    +     [quote=James][/quote]

    +

    +
    +

    James :

    +
    +
    +

    +     [quote][/quote]

    +

    +
    +

    +
    +
    +
    +

    +
    +
    +

    +     [code][/code]

    +

    +
    +

    :

    +
    +
    +
    +

    +
    +
    +

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

    +
    +
    +

    +
    +
    +

    +
    '."\n"; +} + +?> +
    +
    +
    + + +. + + +. + + \ No newline at end of file diff -r 000000000000 -r f9ffdbd96607 punbb/img/index.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/punbb/img/index.html Wed Jul 11 21:01:48 2007 -0400 @@ -0,0 +1,8 @@ + + +. + + +. + + \ No newline at end of file diff -r 000000000000 -r f9ffdbd96607 punbb/img/smilies/big_smile.png Binary file punbb/img/smilies/big_smile.png has changed diff -r 000000000000 -r f9ffdbd96607 punbb/img/smilies/cool.png Binary file punbb/img/smilies/cool.png has changed diff -r 000000000000 -r f9ffdbd96607 punbb/img/smilies/hmm.png Binary file punbb/img/smilies/hmm.png has changed diff -r 000000000000 -r f9ffdbd96607 punbb/img/smilies/index.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/punbb/img/smilies/index.html Wed Jul 11 21:01:48 2007 -0400 @@ -0,0 +1,8 @@ + + +. + + +. + + \ No newline at end of file diff -r 000000000000 -r f9ffdbd96607 punbb/img/smilies/lol.png Binary file punbb/img/smilies/lol.png has changed diff -r 000000000000 -r f9ffdbd96607 punbb/img/smilies/mad.png Binary file punbb/img/smilies/mad.png has changed diff -r 000000000000 -r f9ffdbd96607 punbb/img/smilies/neutral.png Binary file punbb/img/smilies/neutral.png has changed diff -r 000000000000 -r f9ffdbd96607 punbb/img/smilies/roll.png Binary file punbb/img/smilies/roll.png has changed diff -r 000000000000 -r f9ffdbd96607 punbb/img/smilies/sad.png Binary file punbb/img/smilies/sad.png has changed diff -r 000000000000 -r f9ffdbd96607 punbb/img/smilies/smile.png Binary file punbb/img/smilies/smile.png has changed diff -r 000000000000 -r f9ffdbd96607 punbb/img/smilies/tongue.png Binary file punbb/img/smilies/tongue.png has changed diff -r 000000000000 -r f9ffdbd96607 punbb/img/smilies/wink.png Binary file punbb/img/smilies/wink.png has changed diff -r 000000000000 -r f9ffdbd96607 punbb/img/smilies/yikes.png Binary file punbb/img/smilies/yikes.png has changed diff -r 000000000000 -r f9ffdbd96607 punbb/include/cache.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/punbb/include/cache.php Wed Jul 11 21:01:48 2007 -0400 @@ -0,0 +1,205 @@ + $v) + { + if (is_numeric($k)) + $output .= $indent.' '.$k.' => '; + else + $output .= $indent.' \''.str_replace('\'', '\\\'', str_replace('\\', '\\\\', $k)).'\' => '; + + if (is_array($v)) + $output .= var_export($v, true, $indent.' '); + else + { + if (gettype($v) != 'string' && !empty($v)) + $output .= $v.','."\n"; + else + $output .= '\''.str_replace('\'', '\\\'', str_replace('\\', '\\\\', $v)).'\','."\n"; + } + } + + $output .= ($indent != '') ? $indent.'),'."\n" : ')'; + } + else + $output = $args[0]; + + if ($args[1] == true) + return $output; + else + echo $output; + } +} + + +// +// Generate the config cache PHP script +// +function generate_config_cache() +{ + global $db; + + // Get the forum config from the DB + $result = $db->query('SELECT * FROM '.$db->prefix.'config', true) or error('Unable to fetch forum config', __FILE__, __LINE__, $db->error()); + while ($cur_config_item = $db->fetch_row($result)) + $output[$cur_config_item[0]] = $cur_config_item[1]; + + // Output config as PHP code + $fh = @fopen(PUN_ROOT.'cache/cache_config.php', 'wb'); + if (!$fh) + error('Unable to write configuration cache file to cache directory. Please make sure PHP has write access to the directory \'cache\'', __FILE__, __LINE__); + + fwrite($fh, ''); + + fclose($fh); +} + + +// +// Generate the bans cache PHP script +// +function generate_bans_cache() +{ + global $db; + + // Get the ban list from the DB + $result = $db->query('SELECT * FROM '.$db->prefix.'bans', true) or error('Unable to fetch ban list', __FILE__, __LINE__, $db->error()); + + $output = array(); + while ($cur_ban = $db->fetch_assoc($result)) + $output[] = $cur_ban; + + // Output ban list as PHP code + $fh = @fopen(PUN_ROOT.'cache/cache_bans.php', 'wb'); + if (!$fh) + error('Unable to write bans cache file to cache directory. Please make sure PHP has write access to the directory \'cache\'', __FILE__, __LINE__); + + fwrite($fh, ''); + + fclose($fh); +} + + +// +// Generate the ranks cache PHP script +// +function generate_ranks_cache() +{ + global $db; + + // Get the rank list from the DB + $result = $db->query('SELECT * FROM '.$db->prefix.'ranks ORDER BY min_posts', true) or error('Unable to fetch rank list', __FILE__, __LINE__, $db->error()); + + $output = array(); + while ($cur_rank = $db->fetch_assoc($result)) + $output[] = $cur_rank; + + // Output ranks list as PHP code + $fh = @fopen(PUN_ROOT.'cache/cache_ranks.php', 'wb'); + if (!$fh) + error('Unable to write ranks cache file to cache directory. Please make sure PHP has write access to the directory \'cache\'', __FILE__, __LINE__); + + fwrite($fh, ''); + + fclose($fh); +} + + +// +// Generate quickjump cache PHP scripts +// +function generate_quickjump_cache($group_id = false) +{ + global $db, $lang_common, $pun_user; + + // If a group_id was supplied, we generate the quickjump cache for that group only + if ($group_id !== false) + $groups[0] = $group_id; + else + { + // A group_id was now supplied, so we generate the quickjump cache for all groups + $result = $db->query('SELECT g_id FROM '.$db->prefix.'groups') or error('Unable to fetch user group list', __FILE__, __LINE__, $db->error()); + $num_groups = $db->num_rows($result); + + for ($i = 0; $i < $num_groups; ++$i) + $groups[] = $db->result($result, $i); + } + + // Loop through the groups in $groups and output the cache for each of them + while (list(, $group_id) = @each($groups)) + { + // Output quickjump as PHP code + $fh = @fopen(PUN_ROOT.'cache/cache_quickjump_'.$group_id.'.php', 'wb'); + if (!$fh) + error('Unable to write quickjump cache file to cache directory. Please make sure PHP has write access to the directory \'cache\'', __FILE__, __LINE__); + + $output = ''; + $output .= "\t\t\t\t".'
    '."\n\t\t\t\t\t".'
    '."\n\t\t\t\t".'
    '."\n"; + + fwrite($fh, $output); + + fclose($fh); + } +} diff -r 000000000000 -r f9ffdbd96607 punbb/include/common.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/punbb/include/common.php Wed Jul 11 21:01:48 2007 -0400 @@ -0,0 +1,147 @@ +install.php to install PunBB first.'); + + +// Record the start time (will be used to calculate the generation time for the page) +list($usec, $sec) = explode(' ', microtime()); +$pun_start = ((float)$usec + (float)$sec); + +// Make sure PHP reports all errors except E_NOTICE. PunBB supports E_ALL, but a lot of scripts it may interact with, do not. +error_reporting(E_ALL ^ E_NOTICE); + +// Turn off magic_quotes_runtime +set_magic_quotes_runtime(0); + +// Strip slashes from GET/POST/COOKIE (if magic_quotes_gpc is enabled) +if (get_magic_quotes_gpc()) +{ + function stripslashes_array($array) + { + return is_array($array) ? array_map('stripslashes_array', $array) : stripslashes($array); + } + + $_GET = stripslashes_array($_GET); + $_POST = stripslashes_array($_POST); + $_COOKIE = stripslashes_array($_COOKIE); +} + +// Seed the random number generator +mt_srand((double)microtime()*1000000); + +// If a cookie name is not specified in config.php, we use the default (punbb_cookie) +if (empty($cookie_name)) + $cookie_name = 'punbb_cookie'; + +// Define a few commonly used constants +define('PUN_UNVERIFIED', 32000); +define('PUN_ADMIN', 1); +define('PUN_MOD', 2); +define('PUN_GUEST', 3); +define('PUN_MEMBER', 4); + + +// Load DB abstraction layer and connect +require PUN_ROOT.'include/dblayer/common_db.php'; + +// Start a transaction +$db->start_transaction(); + +// Load cached config +@include PUN_ROOT.'cache/cache_config.php'; +if (!defined('PUN_CONFIG_LOADED')) +{ + require PUN_ROOT.'include/cache.php'; + generate_config_cache(); + require PUN_ROOT.'cache/cache_config.php'; +} + + +// Enable output buffering +if (!defined('PUN_DISABLE_BUFFERING')) +{ + // For some very odd reason, "Norton Internet Security" unsets this + $_SERVER['HTTP_ACCEPT_ENCODING'] = isset($_SERVER['HTTP_ACCEPT_ENCODING']) ? $_SERVER['HTTP_ACCEPT_ENCODING'] : ''; + + // Should we use gzip output compression? + if ($pun_config['o_gzip'] && 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 +$pun_user = array(); +check_cookie($pun_user); + +// Attempt to load the common language file +@include PUN_ROOT.'lang/'.$pun_user['language'].'/common.php'; +if (!isset($lang_common)) + exit('There is no valid language pack \''.pun_htmlspecialchars($pun_user['language']).'\' installed. Please reinstall a language of that name.'); + +// Check if we are to display a maintenance message +if ($pun_config['o_maintenance'] && $pun_user['g_id'] > PUN_ADMIN && !defined('PUN_TURN_OFF_MAINT')) + maintenance_message(); + + +// Load cached bans +@include PUN_ROOT.'cache/cache_bans.php'; +if (!defined('PUN_BANS_LOADED')) +{ + require_once PUN_ROOT.'include/cache.php'; + generate_bans_cache(); + require PUN_ROOT.'cache/cache_bans.php'; +} + +// Check if current user is banned +check_bans(); + + +// Update online list +update_users_online(); + diff -r 000000000000 -r f9ffdbd96607 punbb/include/common_admin.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/punbb/include/common_admin.php Wed Jul 11 21:01:48 2007 -0400 @@ -0,0 +1,149 @@ + +
    +
    +

    menu

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

    Plugins

    + + +
    + +query('SELECT id FROM '.$db->prefix.'topics WHERE forum_id='.$forum_id.$extra_sql, true) or error('Unable to fetch topics', __FILE__, __LINE__, $db->error()); + + $topic_ids = ''; + while ($row = $db->fetch_row($result)) + $topic_ids .= (($topic_ids != '') ? ',' : '').$row[0]; + + if ($topic_ids != '') + { + // Fetch posts to prune + $result = $db->query('SELECT id FROM '.$db->prefix.'posts WHERE topic_id IN('.$topic_ids.')', true) or error('Unable to fetch posts', __FILE__, __LINE__, $db->error()); + + $post_ids = ''; + while ($row = $db->fetch_row($result)) + $post_ids .= (($post_ids != '') ? ',' : '').$row[0]; + + if ($post_ids != '') + { + // Delete topics + $db->query('DELETE FROM '.$db->prefix.'topics WHERE id IN('.$topic_ids.')') or error('Unable to prune topics', __FILE__, __LINE__, $db->error()); + // Delete subscriptions + $db->query('DELETE FROM '.$db->prefix.'subscriptions WHERE topic_id IN('.$topic_ids.')') or error('Unable to prune subscriptions', __FILE__, __LINE__, $db->error()); + // Delete posts + $db->query('DELETE FROM '.$db->prefix.'posts WHERE id IN('.$post_ids.')') or error('Unable to prune posts', __FILE__, __LINE__, $db->error()); + + // We removed a bunch of posts, so now we have to update the search index + require_once PUN_ROOT.'include/search_idx.php'; + strip_search_index($post_ids); + } + } +} diff -r 000000000000 -r f9ffdbd96607 punbb/include/dblayer/common_db.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/punbb/include/dblayer/common_db.php Wed Jul 11 21:01:48 2007 -0400 @@ -0,0 +1,70 @@ + + +. + + +. + + \ No newline at end of file diff -r 000000000000 -r f9ffdbd96607 punbb/include/dblayer/mysql.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/punbb/include/dblayer/mysql.php Wed Jul 11 21:01:48 2007 -0400 @@ -0,0 +1,190 @@ +prefix = $db_prefix; + + if ($p_connect) + $this->link_id = @mysql_pconnect($db_host, $db_username, $db_password); + else + $this->link_id = @mysql_connect($db_host, $db_username, $db_password); + + if ($this->link_id) + { + if (@mysql_select_db($db_name, $this->link_id)) + return $this->link_id; + else + error('Unable to select database. MySQL reported: '.mysql_error(), __FILE__, __LINE__); + } + else + error('Unable to connect to MySQL server. MySQL reported: '.mysql_error(), __FILE__, __LINE__); + } + + + function start_transaction() + { + return; + } + + + function end_transaction() + { + return; + } + + + function query($sql, $unbuffered = false) + { + if (defined('PUN_SHOW_QUERIES')) + $q_start = get_microtime(); + + if ($unbuffered) + $this->query_result = @mysql_unbuffered_query($sql, $this->link_id); + else + $this->query_result = @mysql_query($sql, $this->link_id); + + if ($this->query_result) + { + if (defined('PUN_SHOW_QUERIES')) + $this->saved_queries[] = array($sql, sprintf('%.5f', get_microtime() - $q_start)); + + ++$this->num_queries; + + return $this->query_result; + } + else + { + if (defined('PUN_SHOW_QUERIES')) + $this->saved_queries[] = array($sql, 0); + + return false; + } + } + + + function result($query_id = 0, $row = 0) + { + return ($query_id) ? @mysql_result($query_id, $row) : false; + } + + + function fetch_assoc($query_id = 0) + { + return ($query_id) ? @mysql_fetch_assoc($query_id) : false; + } + + + function fetch_row($query_id = 0) + { + return ($query_id) ? @mysql_fetch_row($query_id) : false; + } + + + function num_rows($query_id = 0) + { + return ($query_id) ? @mysql_num_rows($query_id) : false; + } + + + function affected_rows() + { + return ($this->link_id) ? @mysql_affected_rows($this->link_id) : false; + } + + + function insert_id() + { + return ($this->link_id) ? @mysql_insert_id($this->link_id) : false; + } + + + function get_num_queries() + { + return $this->num_queries; + } + + + function get_saved_queries() + { + return $this->saved_queries; + } + + + function free_result($query_id = false) + { + return ($query_id) ? @mysql_free_result($query_id) : false; + } + + + function escape($str) + { + if (is_array($str)) + return ''; + else if (function_exists('mysql_real_escape_string')) + return mysql_real_escape_string($str, $this->link_id); + else + return mysql_escape_string($str); + } + + + function error() + { + $result['error_sql'] = @current(@end($this->saved_queries)); + $result['error_no'] = @mysql_errno($this->link_id); + $result['error_msg'] = @mysql_error($this->link_id); + + return $result; + } + + + function close() + { + if ($this->link_id) + { + if ($this->query_result) + @mysql_free_result($this->query_result); + + return @mysql_close($this->link_id); + } + else + return false; + } +} diff -r 000000000000 -r f9ffdbd96607 punbb/include/dblayer/mysqli.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/punbb/include/dblayer/mysqli.php Wed Jul 11 21:01:48 2007 -0400 @@ -0,0 +1,188 @@ +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, $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 = get_microtime(); + + $this->query_result = @mysqli_query($this->link_id, $sql); + + if ($this->query_result) + { + if (defined('PUN_SHOW_QUERIES')) + $this->saved_queries[] = array($sql, sprintf('%.5f', get_microtime() - $q_start)); + + ++$this->num_queries; + + return $this->query_result; + } + else + { + if (defined('PUN_SHOW_QUERIES')) + $this->saved_queries[] = array($sql, 0); + + return false; + } + } + + + function result($query_id = 0, $row = 0) + { + if ($query_id) + { + if ($row) + @mysqli_data_seek($query_id, $row); + + $cur_row = @mysqli_fetch_row($query_id); + return $cur_row[0]; + } + else + return false; + } + + + function fetch_assoc($query_id = 0) + { + return ($query_id) ? @mysqli_fetch_assoc($query_id) : false; + } + + + function fetch_row($query_id = 0) + { + return ($query_id) ? @mysqli_fetch_row($query_id) : false; + } + + + function num_rows($query_id = 0) + { + return ($query_id) ? @mysqli_num_rows($query_id) : false; + } + + + function affected_rows() + { + return ($this->link_id) ? @mysqli_affected_rows($this->link_id) : false; + } + + + function insert_id() + { + return ($this->link_id) ? @mysqli_insert_id($this->link_id) : false; + } + + + function get_num_queries() + { + return $this->num_queries; + } + + + function get_saved_queries() + { + return $this->saved_queries; + } + + + function free_result($query_id = false) + { + return ($query_id) ? @mysqli_free_result($query_id) : false; + } + + + function escape($str) + { + return is_array($str) ? '' : mysqli_real_escape_string($this->link_id, $str); + } + + + function error() + { + $result['error_sql'] = @current(@end($this->saved_queries)); + $result['error_no'] = @mysqli_errno($this->link_id); + $result['error_msg'] = @mysqli_error($this->link_id); + + return $result; + } + + + function close() + { + if ($this->link_id) + { + if ($this->query_result) + @mysqli_free_result($this->query_result); + + return @mysqli_close($this->link_id); + } + else + return false; + } +} diff -r 000000000000 -r f9ffdbd96607 punbb/include/dblayer/pgsql.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/punbb/include/dblayer/pgsql.php Wed Jul 11 21:01:48 2007 -0400 @@ -0,0 +1,264 @@ +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', __FILE__, __LINE__); + else + return $this->link_id; + } + + + function start_transaction() + { + ++$this->in_transaction; + + return (@pg_query($this->link_id, 'BEGIN')) ? true : false; + } + + + function end_transaction() + { + --$this->in_transaction; + + if (@pg_query($this->link_id, 'COMMIT')) + return true; + else + { + @pg_query($this->link_id, 'ROLLBACK'); + return false; + } + } + + + function query($sql, $unbuffered = false) // $unbuffered is ignored since there is no pgsql_unbuffered_query() + { + if (strrpos($sql, 'LIMIT') !== false) + $sql = preg_replace('#LIMIT ([0-9]+),([ 0-9]+)#', 'LIMIT \\2 OFFSET \\1', $sql); + + if (defined('PUN_SHOW_QUERIES')) + $q_start = get_microtime(); + + @pg_send_query($this->link_id, $sql); + $this->query_result = @pg_get_result($this->link_id); + + if (pg_result_status($this->query_result) != PGSQL_FATAL_ERROR) + { + if (defined('PUN_SHOW_QUERIES')) + $this->saved_queries[] = array($sql, sprintf('%.5f', get_microtime() - $q_start)); + + ++$this->num_queries; + + $this->last_query_text[$this->query_result] = $sql; + + return $this->query_result; + } + else + { + if (defined('PUN_SHOW_QUERIES')) + $this->saved_queries[] = array($sql, 0); + + $this->error_msg = @pg_result_error($this->query_result); + + if ($this->in_transaction) + @pg_query($this->link_id, 'ROLLBACK'); + + --$this->in_transaction; + + return false; + } + } + + + function result($query_id = 0, $row = 0) + { + return ($query_id) ? @pg_fetch_result($query_id, $row, 0) : false; + } + + + function fetch_assoc($query_id = 0) + { + return ($query_id) ? @pg_fetch_assoc($query_id) : false; + } + + + function fetch_row($query_id = 0) + { + return ($query_id) ? @pg_fetch_row($query_id) : false; + } + + + function num_rows($query_id = 0) + { + return ($query_id) ? @pg_num_rows($query_id) : false; + } + + + function affected_rows() + { + return ($this->query_result) ? @pg_affected_rows($this->query_result) : false; + } + + + function insert_id() + { + $query_id = $this->query_result; + + if ($query_id && $this->last_query_text[$query_id] != '') + { + if (preg_match('/^INSERT INTO ([a-z0-9\_\-]+)/is', $this->last_query_text[$query_id], $table_name)) + { + // Hack (don't ask) + if (substr($table_name[1], -6) == 'groups') + $table_name[1] .= '_g'; + + $temp_q_id = @pg_query($this->link_id, 'SELECT currval(\''.$table_name[1].'_id_seq\')'); + return ($temp_q_id) ? intval(@pg_fetch_result($temp_q_id, 0)) : false; + } + } + + return false; + } + + + function get_num_queries() + { + return $this->num_queries; + } + + + function get_saved_queries() + { + return $this->saved_queries; + } + + + function free_result($query_id = false) + { + if (!$query_id) + $query_id = $this->query_result; + + return ($query_id) ? @pg_free_result($query_id) : false; + } + + + function escape($str) + { + return is_array($str) ? '' : pg_escape_string($str); + } + + + function error() + { + $result['error_sql'] = @current(@end($this->saved_queries)); + $result['error_no'] = false; +/* + if (!empty($this->query_result)) + { + $result['error_msg'] = trim(@pg_result_error($this->query_result)); + if ($result['error_msg'] != '') + return $result; + } + + $result['error_msg'] = (!empty($this->link_id)) ? trim(@pg_last_error($this->link_id)) : trim(@pg_last_error()); +*/ + $result['error_msg'] = $this->error_msg; + + return $result; + } + + + function close() + { + if ($this->link_id) + { + if ($this->in_transaction) + { + if (defined('PUN_SHOW_QUERIES')) + $this->saved_queries[] = array('COMMIT', 0); + + @pg_query($this->link_id, 'COMMIT'); + } + + if ($this->query_result) + @pg_free_result($this->query_result); + + return @pg_close($this->link_id); + } + else + return false; + } +} diff -r 000000000000 -r f9ffdbd96607 punbb/include/dblayer/sqlite.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/punbb/include/dblayer/sqlite.php Wed Jul 11 21:01:48 2007 -0400 @@ -0,0 +1,253 @@ +prefix = $db_prefix; + + if (!file_exists($db_name)) + { + @touch($db_name); + @chmod($db_name, 0666); + if (!file_exists($db_name)) + error('Unable to create new database \''.$db_name.'\'. Permission denied', __FILE__, __LINE__); + } + + if (!is_readable($db_name)) + error('Unable to open database \''.$db_name.'\' for reading. Permission denied', __FILE__, __LINE__); + + if (!is_writable($db_name)) + error('Unable to open database \''.$db_name.'\' for writing. Permission denied', __FILE__, __LINE__); + + if ($p_connect) + $this->link_id = @sqlite_popen($db_name, 0666, $sqlite_error); + else + $this->link_id = @sqlite_open($db_name, 0666, $sqlite_error); + + if (!$this->link_id) + error('Unable to open database \''.$db_name.'\'. SQLite reported: '.$sqlite_error, __FILE__, __LINE__); + else + return $this->link_id; + } + + + function start_transaction() + { + ++$this->in_transaction; + + return (@sqlite_query($this->link_id, 'BEGIN')) ? true : false; + } + + + function end_transaction() + { + --$this->in_transaction; + + if (@sqlite_query($this->link_id, 'COMMIT')) + return true; + else + { + @sqlite_query($this->link_id, 'ROLLBACK'); + return false; + } + } + + + function query($sql, $unbuffered = false) + { + if (defined('PUN_SHOW_QUERIES')) + $q_start = get_microtime(); + + if ($unbuffered) + $this->query_result = @sqlite_unbuffered_query($this->link_id, $sql); + else + $this->query_result = @sqlite_query($this->link_id, $sql); + + if ($this->query_result) + { + if (defined('PUN_SHOW_QUERIES')) + $this->saved_queries[] = array($sql, sprintf('%.5f', get_microtime() - $q_start)); + + ++$this->num_queries; + + return $this->query_result; + } + else + { + if (defined('PUN_SHOW_QUERIES')) + $this->saved_queries[] = array($sql, 0); + + $this->error_no = @sqlite_last_error($this->link_id); + $this->error_msg = @sqlite_error_string($this->error_no); + + if ($this->in_transaction) + @sqlite_query($this->link_id, 'ROLLBACK'); + + --$this->in_transaction; + + return false; + } + } + + + function result($query_id = 0, $row = 0) + { + if ($query_id) + { + if ($row != 0) + @sqlite_seek($query_id, $row); + + return @current(@sqlite_current($query_id)); + } + else + return false; + } + + + function fetch_assoc($query_id = 0) + { + if ($query_id) + { + $cur_row = @sqlite_fetch_array($query_id, SQLITE_ASSOC); + if ($cur_row) + { + // Horrible hack to get rid of table names and table aliases from the array keys + while (list($key, $value) = @each($cur_row)) + { + $dot_spot = strpos($key, '.'); + if ($dot_spot !== false) + { + unset($cur_row[$key]); + $key = substr($key, $dot_spot+1); + $cur_row[$key] = $value; + } + } + } + + return $cur_row; + } + else + return false; + } + + + function fetch_row($query_id = 0) + { + return ($query_id) ? @sqlite_fetch_array($query_id, SQLITE_NUM) : false; + } + + + function num_rows($query_id = 0) + { + return ($query_id) ? @sqlite_num_rows($query_id) : false; + } + + + function affected_rows() + { + return ($this->query_result) ? @sqlite_changes($this->query_result) : false; + } + + + function insert_id() + { + return ($this->link_id) ? @sqlite_last_insert_rowid($this->link_id) : false; + } + + + function get_num_queries() + { + return $this->num_queries; + } + + + function get_saved_queries() + { + return $this->saved_queries; + } + + + function free_result($query_id = false) + { + return true; + } + + + function escape($str) + { + return is_array($str) ? '' : sqlite_escape_string($str); + } + + + function error() + { + $result['error_sql'] = @current(@end($this->saved_queries)); + $result['error_no'] = $this->error_no; + $result['error_msg'] = $this->error_msg; + + return $result; + } + + + function close() + { + if ($this->link_id) + { + if ($this->in_transaction) + { + if (defined('PUN_SHOW_QUERIES')) + $this->saved_queries[] = array('COMMIT', 0); + + @sqlite_query($this->link_id, 'COMMIT'); + } + + return @sqlite_close($this->link_id); + } + else + return false; + } +} diff -r 000000000000 -r f9ffdbd96607 punbb/include/email.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/punbb/include/email.php Wed Jul 11 21:01:48 2007 -0400 @@ -0,0 +1,186 @@ + 50) + return false; + + return preg_match('/^(([^<>()[\]\\.,;:\s@"\']+(\.[^<>()[\]\\.,;:\s@"\']+)*)|("[^"\']+"))@((\[\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\])|(([a-zA-Z\d\-]+\.)+[a-zA-Z]{2,}))$/', $email); +} + + +// +// Check if $email is banned +// +function is_banned_email($email) +{ + global $db, $pun_bans; + + foreach ($pun_bans as $cur_ban) + { + if ($cur_ban['email'] != '' && + ($email == $cur_ban['email'] || + (strpos($cur_ban['email'], '@') === false && stristr($email, '@'.$cur_ban['email'])))) + return true; + } + + return false; +} + + +// +// Wrapper for PHP's mail() +// +function pun_mail($to, $subject, $message, $from = '') +{ + global $pun_config, $lang_common; + + // Default sender/return address + if (!$from) + $from = '"'.str_replace('"', '', $pun_config['o_board_title'].' '.$lang_common['Mailer']).'" <'.$pun_config['o_webmaster_email'].'>'; + + // Do a little spring cleaning + $to = trim(preg_replace('#[\n\r]+#s', '', $to)); + $subject = trim(preg_replace('#[\n\r]+#s', '', $subject)); + $from = trim(preg_replace('#[\n\r:]+#s', '', $from)); + + $headers = 'From: '.$from."\r\n".'Date: '.date('r')."\r\n".'MIME-Version: 1.0'."\r\n".'Content-transfer-encoding: 8bit'."\r\n".'Content-type: text/plain; charset='.$lang_common['lang_encoding']."\r\n".'X-Mailer: PunBB Mailer'; + + // Make sure all linebreaks are CRLF in message (and strip out any NULL bytes) + $message = str_replace(array("\n", "\0"), array("\r\n", ''), pun_linebreaks($message)); + + if ($pun_config['o_smtp_host'] != '') + smtp_mail($to, $subject, $message, $headers); + else + { + // Change the linebreaks used in the headers according to OS + if (strtoupper(substr(PHP_OS, 0, 3)) == 'MAC') + $headers = str_replace("\r\n", "\r", $headers); + else if (strtoupper(substr(PHP_OS, 0, 3)) != 'WIN') + $headers = str_replace("\r\n", "\n", $headers); + + mail($to, $subject, $message, $headers); + } +} + + +// +// This function was originally a part of the phpBB Group forum software phpBB2 (http://www.phpbb.com). +// They deserve all the credit for writing it. I made small modifications for it to suit PunBB and it's coding standards. +// +function server_parse($socket, $expected_response) +{ + $server_response = ''; + while (substr($server_response, 3, 1) != ' ') + { + if (!($server_response = fgets($socket, 256))) + error('Couldn\'t get mail server response codes. Please contact the forum administrator.', __FILE__, __LINE__); + } + + if (!(substr($server_response, 0, 3) == $expected_response)) + error('Unable to send e-mail. Please contact the forum administrator with the following error message reported by the SMTP server: "'.$server_response.'"', __FILE__, __LINE__); +} + + +// +// This function was originally a part of the phpBB Group forum software phpBB2 (http://www.phpbb.com). +// They deserve all the credit for writing it. I made small modifications for it to suit PunBB and it's coding standards. +// +function smtp_mail($to, $subject, $message, $headers = '') +{ + global $pun_config; + + $recipients = explode(',', $to); + + // Are we using port 25 or a custom port? + if (strpos($pun_config['o_smtp_host'], ':') !== false) + list($smtp_host, $smtp_port) = explode(':', $pun_config['o_smtp_host']); + else + { + $smtp_host = $pun_config['o_smtp_host']; + $smtp_port = 25; + } + + if (!($socket = fsockopen($smtp_host, $smtp_port, $errno, $errstr, 15))) + error('Could not connect to smtp host "'.$pun_config['o_smtp_host'].'" ('.$errno.') ('.$errstr.')', __FILE__, __LINE__); + + server_parse($socket, '220'); + + if ($pun_config['o_smtp_user'] != '' && $pun_config['o_smtp_pass'] != '') + { + fwrite($socket, 'EHLO '.$smtp_host."\r\n"); + server_parse($socket, '250'); + + fwrite($socket, 'AUTH LOGIN'."\r\n"); + server_parse($socket, '334'); + + fwrite($socket, base64_encode($pun_config['o_smtp_user'])."\r\n"); + server_parse($socket, '334'); + + fwrite($socket, base64_encode($pun_config['o_smtp_pass'])."\r\n"); + server_parse($socket, '235'); + } + else + { + fwrite($socket, 'HELO '.$smtp_host."\r\n"); + server_parse($socket, '250'); + } + + fwrite($socket, 'MAIL FROM: <'.$pun_config['o_webmaster_email'].'>'."\r\n"); + server_parse($socket, '250'); + + $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 -r 000000000000 -r f9ffdbd96607 punbb/include/functions.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/punbb/include/functions.php Wed Jul 11 21:01:48 2007 -0400 @@ -0,0 +1,1110 @@ + 1, 'password_hash' => 'Guest'); + + // If a cookie is set, we get the user_id and password hash from it + if (isset($_COOKIE[$cookie_name])) + list($cookie['user_id'], $cookie['password_hash']) = @unserialize($_COOKIE[$cookie_name]); + + if ($cookie['user_id'] > 1) + { + // Check if there's a user with the user ID and password hash from the cookie + $result = $db->query('SELECT u.*, g.*, o.logged, o.idle FROM '.$db->prefix.'users AS u INNER JOIN '.$db->prefix.'groups AS g ON u.group_id=g.g_id LEFT JOIN '.$db->prefix.'online AS o ON o.user_id=u.id WHERE u.id='.intval($cookie['user_id'])) or error('Unable to fetch user information', __FILE__, __LINE__, $db->error()); + $pun_user = $db->fetch_assoc($result); + + // If user authorisation failed + if (!isset($pun_user['id']) || md5($cookie_seed.$pun_user['password']) !== $cookie['password_hash']) + { + pun_setcookie(0, random_pass(8), $expire); + set_default_user(); + + return; + } + + // Set a default language if the user selected language no longer exists + if (!@file_exists(PUN_ROOT.'lang/'.$pun_user['language'])) + $pun_user['language'] = $pun_config['o_default_lang']; + + // Set a default style if the user selected style no longer exists + if (!@file_exists(PUN_ROOT.'style/'.$pun_user['style'].'.css')) + $pun_user['style'] = $pun_config['o_default_style']; + + if (!$pun_user['disp_topics']) + $pun_user['disp_topics'] = $pun_config['o_disp_topics_default']; + if (!$pun_user['disp_posts']) + $pun_user['disp_posts'] = $pun_config['o_disp_posts_default']; + + if ($pun_user['save_pass'] == '0') + $expire = 0; + + // Define this if you want this visit to affect the online list and the users last visit data + if (!defined('PUN_QUIET_VISIT')) + { + // Update the online list + if (!$pun_user['logged']) + { + $pun_user['logged'] = $now; + + // With MySQL/MySQLi, REPLACE INTO avoids a user having two rows in the online table + switch ($db_type) + { + case 'mysql': + case 'mysqli': + $db->query('REPLACE INTO '.$db->prefix.'online (user_id, ident, logged) VALUES('.$pun_user['id'].', \''.$db->escape($pun_user['username']).'\', '.$pun_user['logged'].')') or error('Unable to insert into online list', __FILE__, __LINE__, $db->error()); + break; + + default: + $db->query('INSERT INTO '.$db->prefix.'online (user_id, ident, logged) VALUES('.$pun_user['id'].', \''.$db->escape($pun_user['username']).'\', '.$pun_user['logged'].')') or error('Unable to insert into online list', __FILE__, __LINE__, $db->error()); + break; + } + } + else + { + // Special case: We've timed out, but no other user has browsed the forums since we timed out + if ($pun_user['logged'] < ($now-$pun_config['o_timeout_visit'])) + { + $db->query('UPDATE '.$db->prefix.'users SET last_visit='.$pun_user['logged'].' WHERE id='.$pun_user['id']) or error('Unable to update user visit data', __FILE__, __LINE__, $db->error()); + $pun_user['last_visit'] = $pun_user['logged']; + } + + $idle_sql = ($pun_user['idle'] == '1') ? ', idle=0' : ''; + $db->query('UPDATE '.$db->prefix.'online SET logged='.$now.$idle_sql.' WHERE user_id='.$pun_user['id']) or error('Unable to update online list', __FILE__, __LINE__, $db->error()); + } + } + + $pun_user['is_guest'] = false; + } + else + set_default_user(); +} + + +// +// Fill $pun_user with default values (for guests) +// +function set_default_user() +{ + global $db, $db_type, $pun_user, $pun_config; + + $remote_addr = get_remote_address(); + + // Fetch guest user + $result = $db->query('SELECT u.*, g.*, o.logged FROM '.$db->prefix.'users AS u INNER JOIN '.$db->prefix.'groups AS g ON u.group_id=g.g_id LEFT JOIN '.$db->prefix.'online AS o ON o.ident=\''.$remote_addr.'\' WHERE u.id=1') or error('Unable to fetch guest information', __FILE__, __LINE__, $db->error()); + if (!$db->num_rows($result)) + exit('Unable to fetch guest information. The table \''.$db->prefix.'users\' must contain an entry with id = 1 that represents anonymous users.'); + + $pun_user = $db->fetch_assoc($result); + + // Update online list + if (!$pun_user['logged']) + { + $pun_user['logged'] = time(); + + // With MySQL/MySQLi, REPLACE INTO avoids a user having two rows in the online table + switch ($db_type) + { + case 'mysql': + case 'mysqli': + $db->query('REPLACE INTO '.$db->prefix.'online (user_id, ident, logged) VALUES(1, \''.$db->escape($remote_addr).'\', '.$pun_user['logged'].')') or error('Unable to insert into online list', __FILE__, __LINE__, $db->error()); + break; + + default: + $db->query('INSERT INTO '.$db->prefix.'online (user_id, ident, logged) VALUES(1, \''.$db->escape($remote_addr).'\', '.$pun_user['logged'].')') or error('Unable to insert into online list', __FILE__, __LINE__, $db->error()); + break; + } + } + else + $db->query('UPDATE '.$db->prefix.'online SET logged='.time().' WHERE ident=\''.$db->escape($remote_addr).'\'') or error('Unable to update online list', __FILE__, __LINE__, $db->error()); + + $pun_user['disp_topics'] = $pun_config['o_disp_topics_default']; + $pun_user['disp_posts'] = $pun_config['o_disp_posts_default']; + $pun_user['timezone'] = $pun_config['o_server_timezone']; + $pun_user['language'] = $pun_config['o_default_lang']; + $pun_user['style'] = $pun_config['o_default_style']; + $pun_user['is_guest'] = true; +} + + +// +// Set a cookie, PunBB style! +// +function pun_setcookie($user_id, $password_hash, $expire) +{ + global $cookie_name, $cookie_path, $cookie_domain, $cookie_secure, $cookie_seed; + + // Enable sending of a P3P header by removing // from the following line (try this if login is failing in IE6) +// @header('P3P: CP="CUR ADM"'); + + if (version_compare(PHP_VERSION, '5.2.0', '>=')) + setcookie($cookie_name, serialize(array($user_id, md5($cookie_seed.$password_hash))), $expire, $cookie_path, $cookie_domain, $cookie_secure, true); + else + setcookie($cookie_name, serialize(array($user_id, md5($cookie_seed.$password_hash))), $expire, $cookie_path.'; HttpOnly', $cookie_domain, $cookie_secure); +} + + +// +// Check whether the connecting user is banned (and delete any expired bans while we're at it) +// +function check_bans() +{ + global $db, $pun_config, $lang_common, $pun_user, $pun_bans; + + // Admins aren't affected + if ($pun_user['g_id'] == PUN_ADMIN || !$pun_bans) + return; + + // Add a dot at the end of the IP address to prevent banned address 192.168.0.5 from matching e.g. 192.168.0.50 + $user_ip = get_remote_address().'.'; + $bans_altered = false; + + foreach ($pun_bans as $cur_ban) + { + // Has this ban expired? + if ($cur_ban['expire'] != '' && $cur_ban['expire'] <= time()) + { + $db->query('DELETE FROM '.$db->prefix.'bans WHERE id='.$cur_ban['id']) or error('Unable to delete expired ban', __FILE__, __LINE__, $db->error()); + $bans_altered = true; + continue; + } + + if ($cur_ban['username'] != '' && !strcasecmp($pun_user['username'], $cur_ban['username'])) + { + $db->query('DELETE FROM '.$db->prefix.'online WHERE ident=\''.$db->escape($pun_user['username']).'\'') or error('Unable to delete from online list', __FILE__, __LINE__, $db->error()); + message($lang_common['Ban message'].' '.(($cur_ban['expire'] != '') ? $lang_common['Ban message 2'].' '.strtolower(format_time($cur_ban['expire'], true)).'. ' : '').(($cur_ban['message'] != '') ? $lang_common['Ban message 3'].'

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

    ' : '

    ').$lang_common['Ban message 4'].' '.$pun_config['o_admin_email'].'.', true); + } + + if ($cur_ban['ip'] != '') + { + $cur_ban_ips = explode(' ', $cur_ban['ip']); + + for ($i = 0; $i < count($cur_ban_ips); ++$i) + { + $cur_ban_ips[$i] = $cur_ban_ips[$i].'.'; + + if (substr($user_ip, 0, strlen($cur_ban_ips[$i])) == $cur_ban_ips[$i]) + { + $db->query('DELETE FROM '.$db->prefix.'online WHERE ident=\''.$db->escape($pun_user['username']).'\'') or error('Unable to delete from online list', __FILE__, __LINE__, $db->error()); + message($lang_common['Ban message'].' '.(($cur_ban['expire'] != '') ? $lang_common['Ban message 2'].' '.strtolower(format_time($cur_ban['expire'], true)).'. ' : '').(($cur_ban['message'] != '') ? $lang_common['Ban message 3'].'

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

    ' : '

    ').$lang_common['Ban message 4'].' '.$pun_config['o_admin_email'].'.', true); + } + } + } + } + + // If we removed any expired bans during our run-through, we need to regenerate the bans cache + if ($bans_altered) + { + require_once PUN_ROOT.'include/cache.php'; + generate_bans_cache(); + } +} + + +// +// Update "Users online" +// +function update_users_online() +{ + global $db, $pun_config, $pun_user; + + $now = time(); + + // Fetch all online list entries that are older than "o_timeout_online" + $result = $db->query('SELECT * FROM '.$db->prefix.'online WHERE logged<'.($now-$pun_config['o_timeout_online'])) or error('Unable to fetch old entries from online list', __FILE__, __LINE__, $db->error()); + while ($cur_user = $db->fetch_assoc($result)) + { + // If the entry is a guest, delete it + if ($cur_user['user_id'] == '1') + $db->query('DELETE FROM '.$db->prefix.'online WHERE ident=\''.$db->escape($cur_user['ident']).'\'') or error('Unable to delete from online list', __FILE__, __LINE__, $db->error()); + else + { + // If the entry is older than "o_timeout_visit", update last_visit for the user in question, then delete him/her from the online list + if ($cur_user['logged'] < ($now-$pun_config['o_timeout_visit'])) + { + $db->query('UPDATE '.$db->prefix.'users SET last_visit='.$cur_user['logged'].' WHERE id='.$cur_user['user_id']) or error('Unable to update user visit data', __FILE__, __LINE__, $db->error()); + $db->query('DELETE FROM '.$db->prefix.'online WHERE user_id='.$cur_user['user_id']) or error('Unable to delete from online list', __FILE__, __LINE__, $db->error()); + } + else if ($cur_user['idle'] == '0') + $db->query('UPDATE '.$db->prefix.'online SET idle=1 WHERE user_id='.$cur_user['user_id']) or error('Unable to insert into online list', __FILE__, __LINE__, $db->error()); + } + } +} + + +// +// Generate the "navigator" that appears at the top of every page +// +function generate_navlinks() +{ + global $pun_config, $lang_common, $pun_user; + + // Index and Userlist should always be displayed + $links[] = '
    '."\n\n"; + + ++$cat_count; + +?> +
    +

    +
    +
    + + + + + + + + + + + $pun_user['last_visit']) + { + $item_status = 'inew'; + $icon_text = $lang_common['New icon']; + $icon_type = 'icon inew'; + } + + // Is this a redirect forum? + if ($cur_forum['redirect_url'] != '') + { + $forum_field = '

    '.pun_htmlspecialchars($cur_forum['forum_name']).'

    '; + $num_topics = $num_posts = ' '; + $item_status = 'iredirect'; + $icon_text = $lang_common['Redirect icon']; + $icon_type = 'icon'; + } + else + { + $forum_field = '

    '.pun_htmlspecialchars($cur_forum['forum_name']).'

    '; + $num_topics = $cur_forum['num_topics']; + $num_posts = $cur_forum['num_posts']; + } + + if ($cur_forum['forum_desc'] != '') + $forum_field .= "\n\t\t\t\t\t\t\t\t".$cur_forum['forum_desc']; + + + // If there is a last_post/last_poster. + if ($cur_forum['last_post'] != '') + $last_post = ''.format_time($cur_forum['last_post']).''.$lang_common['by'].' '.pun_htmlspecialchars($cur_forum['last_poster']).''; + else + $last_post = ' '; + + if ($cur_forum['moderators'] != '') + { + $mods_array = unserialize($cur_forum['moderators']); + $moderators = array(); + + while (list($mod_username, $mod_id) = @each($mods_array)) + $moderators[] = ''.pun_htmlspecialchars($mod_username).''; + + $moderators = "\t\t\t\t\t\t\t\t".'

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

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

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

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

    +
    +
    +
    +
    +
    '. $stats['total_users'] ?>
    +
    '.$stats['total_topics'] ?>
    +
    '.$stats['total_posts'] ?>
    +
    +
    +
    +
    :
    +query('SELECT user_id, ident FROM '.$db->prefix.'online WHERE idle=0 ORDER BY ident', true) or error('Unable to fetch online list', __FILE__, __LINE__, $db->error()); + + while ($pun_user_online = $db->fetch_assoc($result)) + { + if ($pun_user_online['user_id'] > 1) + $users[] = "\n\t\t\t\t".'
    '.pun_htmlspecialchars($pun_user_online['ident']).''; + else + ++$num_guests; + } + + $num_users = count($users); + echo "\t\t\t\t".'
    '. $lang_index['Users online'].': '.$num_users.'
    '."\n\t\t\t\t".'
    '.$lang_index['Guests online'].': '.$num_guests.'
    '."\n\t\t\t".'
    '."\n"; + + + if ($num_users > 0) + echo "\t\t\t".'
    '."\n\t\t\t\t".'
    '.$lang_index['Online'].': 
    '."\t\t\t\t".implode(', ', $users).''."\n\t\t\t".'
    '."\n"; + else + echo "\t\t\t".'
    '."\n"; + +} +else + echo "\t\t".''."\n\t\t\t".'
    '."\n"; + + +?> +
    +
    +
    +here instead.'); + + +// Make sure we are running at least PHP 4.1.0 +if (intval(str_replace('.', '', phpversion())) < 410) + exit('You are running PHP version '.PHP_VERSION.'. PunBB requires at least PHP 4.1.0 to run properly. You must upgrade your PHP installation before you can continue.'); + +// Disable error reporting for uninitialized variables +error_reporting(E_ALL); + +// Turn off PHP time limit +@set_time_limit(0); + + +if (!isset($_POST['form_sent'])) +{ + // Determine available database extensions + $dual_mysql = false; + $db_extensions = array(); + if (function_exists('mysqli_connect')) + $db_extensions[] = array('mysqli', 'MySQL Improved'); + if (function_exists('mysql_connect')) + { + $db_extensions[] = array('mysql', 'MySQL Standard'); + + if (count($db_extensions) > 1) + $dual_mysql = true; + } + if (function_exists('sqlite_open')) + $db_extensions[] = array('sqlite', 'SQLite'); + if (function_exists('pg_connect')) + $db_extensions[] = array('pgsql', 'PostgreSQL'); + + if (empty($db_extensions)) + exit('This PHP environment does not have support for any of the databases that PunBB supports. PHP needs to have support for either MySQL, PostgreSQL or SQLite in order for PunBB to be installed.'); + +?> + + + + + +PunBB Installation + + + + + +
    +
    + +
    +

    PunBB Installation

    +
    +
    +

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

    +
    +
    +
    + +
    +

    Install PunBB 1.2

    +
    +
    +
    +
    +
    +

    Database setup

    +

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

    +
    +
    + Select your database type +
    +

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

    +

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

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

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

    + +
    +
    +
    +
    +
    + Enter then name of your database +
    +

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

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

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

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

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

    + +
    +
    +
    +
    +
    +

    Administration setup

    +

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

    +
    +
    + Enter Administrators username +
    +

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

    + +
    +
    +
    +
    +
    + Enter and confirm Administrator password +
    +

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

    + + +
    +
    +
    +
    +
    +
    + Enter Administrator's e-mail +
    +

    The e-mail address of the forum administrator.

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

    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. Please note that the preset value below is just an educated guess by PunBB.

    + +
    +
    +
    +

    +
    +
    +
    + +
    +
    + + + +An error occured on line '.$line.' in file '.$file.'.

    '; + else + echo 'An error occured.

    '; + + echo 'PunBB reported: '.htmlspecialchars($message).'

    '; + + if ($db_error !== false) + echo 'Database reported: '.htmlspecialchars($db_error['error_msg']).(($db_error['error_no']) ? ' (Errno: '.$db_error['error_no'].')' : ''); + + exit; + } + + + $db_type = $_POST['req_db_type']; + $db_host = trim($_POST['req_db_host']); + $db_name = trim($_POST['req_db_name']); + $db_username = unescape(trim($_POST['db_username'])); + $db_password = unescape(trim($_POST['db_password'])); + $db_prefix = trim($_POST['db_prefix']); + $username = unescape(trim($_POST['req_username'])); + $email = strtolower(trim($_POST['req_email'])); + $password1 = unescape(trim($_POST['req_password1'])); + $password2 = unescape(trim($_POST['req_password2'])); + + + // Make sure base_url doesn't end with a slash + if (substr($_POST['req_base_url'], -1) == '/') + $base_url = substr($_POST['req_base_url'], 0, -1); + else + $base_url = $_POST['req_base_url']; + + + // Validate username and passwords + if (strlen($username) < 2) + error('Usernames must be at least 2 characters long. Please go back and correct.'); + if (strlen($password1) < 4) + error('Passwords must be at least 4 characters long. Please go back and correct.'); + if ($password1 != $password2) + error('Passwords do not match. Please go back and correct.'); + if (!strcasecmp($username, 'Guest')) + error('The username guest is reserved. Please go back and correct.'); + if (preg_match('/[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}/', $username)) + error('Usernames may not be in the form of an IP address. Please go back and correct.'); + if (preg_match('#\[b\]|\[/b\]|\[u\]|\[/u\]|\[i\]|\[/i\]|\[color|\[/color\]|\[quote\]|\[/quote\]|\[code\]|\[/code\]|\[img\]|\[/img\]|\[url|\[/url\]|\[email|\[/email\]#i', $username)) + error('Usernames may not contain any of the text formatting tags (BBCode) that the forum uses. Please go back and correct.'); + + if (strlen($email) > 50 || !preg_match('/^(([^<>()[\]\\.,;:\s@"\']+(\.[^<>()[\]\\.,;:\s@"\']+)*)|("[^"\']+"))@((\[\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\])|(([a-zA-Z\d\-]+\.)+[a-zA-Z]{2,}))$/', $email)) + error('The administrator e-mail address you entered is invalid. Please go back and correct.'); + + + // Load the appropriate DB layer class + switch ($db_type) + { + case 'mysql': + require PUN_ROOT.'include/dblayer/mysql.php'; + break; + + case 'mysqli': + require PUN_ROOT.'include/dblayer/mysqli.php'; + break; + + case 'pgsql': + require PUN_ROOT.'include/dblayer/pgsql.php'; + break; + + case 'sqlite': + require PUN_ROOT.'include/dblayer/sqlite.php'; + break; + + default: + error('\''.$db_type.'\' is not a valid database type.'); + } + + // Create the database object (and connect/select db) + $db = new DBLayer($db_host, $db_username, $db_password, $db_name, $db_prefix, false); + + + // Do some DB type specific checks + switch ($db_type) + { + case 'mysql': + case 'mysqli': + break; + + case 'pgsql': + // Make sure we are running at least PHP 4.3.0 (needed only for PostgreSQL) + if (version_compare(PHP_VERSION, '4.3.0', '<')) + error('You are running PHP version '.PHP_VERSION.'. PunBB requires at least PHP 4.3.0 to run properly when using PostgreSQL. You must upgrade your PHP installation or use a different database before you can continue.'); + break; + + case 'sqlite': + if (strtolower($db_prefix) == 'sqlite_') + error('The table prefix \'sqlite_\' is reserved for use by the SQLite engine. Please choose a different prefix.'); + break; + } + + + // Make sure PunBB isn't already installed + $result = $db->query('SELECT 1 FROM '.$db_prefix.'users WHERE id=1'); + if ($db->num_rows($result)) + error('A table called "'.$db_prefix.'users" is already present in the database "'.$db_name.'". This could mean that PunBB is already installed or that another piece of software is installed and is occupying one or more of the table names PunBB requires. If you want to install multiple copies of PunBB in the same database, you must choose a different table prefix.'); + + + // Create all tables + switch ($db_type) + { + case 'mysql': + case 'mysqli': + $sql = 'CREATE TABLE '.$db_prefix."bans ( + id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, + username VARCHAR(200), + ip VARCHAR(255), + email VARCHAR(50), + message VARCHAR(255), + expire INT(10) UNSIGNED, + PRIMARY KEY (id) + ) TYPE=MyISAM;"; + break; + + case 'pgsql': + $db->start_transaction(); + + $sql = 'CREATE TABLE '.$db_prefix."bans ( + id SERIAL, + username VARCHAR(200), + ip VARCHAR(255), + email VARCHAR(50), + message VARCHAR(255), + expire INT, + PRIMARY KEY (id) + )"; + break; + + case 'sqlite': + $db->start_transaction(); + + $sql = 'CREATE TABLE '.$db_prefix."bans ( + id INTEGER NOT NULL, + username VARCHAR(200), + ip VARCHAR(255), + email VARCHAR(50), + message VARCHAR(255), + expire INTEGER, + PRIMARY KEY (id) + )"; + break; + + } + + $db->query($sql) or error('Unable to create table '.$db_prefix.'bans. Please check your settings and try again.', __FILE__, __LINE__, $db->error()); + + + switch ($db_type) + { + case 'mysql': + case 'mysqli': + $sql = 'CREATE TABLE '.$db_prefix."categories ( + id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, + cat_name VARCHAR(80) NOT NULL DEFAULT 'New Category', + disp_position INT(10) NOT NULL DEFAULT 0, + PRIMARY KEY (id) + ) TYPE=MyISAM;"; + break; + + case 'pgsql': + $sql = 'CREATE TABLE '.$db_prefix."categories ( + id SERIAL, + cat_name VARCHAR(80) NOT NULL DEFAULT 'New Category', + disp_position INT NOT NULL DEFAULT 0, + PRIMARY KEY (id) + )"; + break; + + case 'sqlite': + $sql = 'CREATE TABLE '.$db_prefix."categories ( + id INTEGER NOT NULL, + cat_name VARCHAR(80) NOT NULL DEFAULT 'New Category', + disp_position INTEGER NOT NULL DEFAULT 0, + PRIMARY KEY (id) + )"; + break; + } + + $db->query($sql) or error('Unable to create table '.$db_prefix.'categories. Please check your settings and try again.', __FILE__, __LINE__, $db->error()); + + + + switch ($db_type) + { + case 'mysql': + case 'mysqli': + $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) + ) TYPE=MyISAM;"; + 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; + + case 'sqlite': + $sql = 'CREATE TABLE '.$db_prefix."censoring ( + id INTEGER NOT NULL, + search_for VARCHAR(60) NOT NULL DEFAULT '', + replace_with VARCHAR(60) NOT NULL DEFAULT '', + PRIMARY KEY (id) + )"; + break; + } + + $db->query($sql) or error('Unable to create table '.$db_prefix.'censoring. Please check your settings and try again.', __FILE__, __LINE__, $db->error()); + + + + switch ($db_type) + { + case 'mysql': + case 'mysqli': + $sql = 'CREATE TABLE '.$db_prefix."config ( + conf_name VARCHAR(255) NOT NULL DEFAULT '', + conf_value TEXT, + PRIMARY KEY (conf_name) + ) TYPE=MyISAM;"; + break; + + case 'pgsql': + $sql = 'CREATE TABLE '.$db_prefix."config ( + conf_name VARCHAR(255) NOT NULL DEFAULT '', + conf_value TEXT, + PRIMARY KEY (conf_name) + )"; + break; + + case 'sqlite': + $sql = 'CREATE TABLE '.$db_prefix."config ( + conf_name VARCHAR(255) NOT NULL DEFAULT '', + conf_value TEXT, + PRIMARY KEY (conf_name) + )"; + break; + } + + $db->query($sql) or error('Unable to create table '.$db_prefix.'config. Please check your settings and try again.', __FILE__, __LINE__, $db->error()); + + + + switch ($db_type) + { + case 'mysql': + case 'mysqli': + $sql = 'CREATE TABLE '.$db_prefix."forum_perms ( + group_id INT(10) NOT NULL DEFAULT 0, + forum_id INT(10) NOT NULL DEFAULT 0, + read_forum TINYINT(1) NOT NULL DEFAULT 1, + post_replies TINYINT(1) NOT NULL DEFAULT 1, + post_topics TINYINT(1) NOT NULL DEFAULT 1, + PRIMARY KEY (group_id, forum_id) + ) TYPE=MyISAM;"; + break; + + case 'pgsql': + $sql = 'CREATE TABLE '.$db_prefix."forum_perms ( + group_id INT NOT NULL DEFAULT 0, + forum_id INT NOT NULL DEFAULT 0, + read_forum SMALLINT NOT NULL DEFAULT 1, + post_replies SMALLINT NOT NULL DEFAULT 1, + post_topics SMALLINT NOT NULL DEFAULT 1, + PRIMARY KEY (group_id, forum_id) + )"; + break; + + case 'sqlite': + $sql = 'CREATE TABLE '.$db_prefix."forum_perms ( + group_id INTEGER NOT NULL DEFAULT 0, + forum_id INTEGER NOT NULL DEFAULT 0, + read_forum INTEGER NOT NULL DEFAULT 1, + post_replies INTEGER NOT NULL DEFAULT 1, + post_topics INTEGER NOT NULL DEFAULT 1, + PRIMARY KEY (group_id, forum_id) + )"; + break; + } + + $db->query($sql) or error('Unable to create table '.$db_prefix.'forum_perms. Please check your settings and try again.', __FILE__, __LINE__, $db->error()); + + + + switch ($db_type) + { + case 'mysql': + case 'mysqli': + $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, + redirect_url VARCHAR(100), + moderators TEXT, + num_topics MEDIUMINT(8) UNSIGNED NOT NULL DEFAULT 0, + num_posts MEDIUMINT(8) UNSIGNED NOT NULL DEFAULT 0, + last_post INT(10) UNSIGNED, + last_post_id INT(10) UNSIGNED, + last_poster VARCHAR(200), + sort_by TINYINT(1) NOT NULL DEFAULT 0, + disp_position INT(10) NOT NULL DEFAULT 0, + cat_id INT(10) UNSIGNED NOT NULL DEFAULT 0, + PRIMARY KEY (id) + ) TYPE=MyISAM;"; + break; + + case 'pgsql': + $sql = 'CREATE TABLE '.$db_prefix."forums ( + id SERIAL, + forum_name VARCHAR(80) NOT NULL DEFAULT 'New forum', + forum_desc TEXT, + redirect_url VARCHAR(100), + moderators TEXT, + num_topics INT NOT NULL DEFAULT 0, + num_posts INT NOT NULL DEFAULT 0, + last_post INT, + last_post_id INT, + last_poster VARCHAR(200), + sort_by SMALLINT NOT NULL DEFAULT 0, + disp_position INT NOT NULL DEFAULT 0, + cat_id INT NOT NULL DEFAULT 0, + PRIMARY KEY (id) + )"; + break; + + case 'sqlite': + $sql = 'CREATE TABLE '.$db_prefix."forums ( + id INTEGER NOT NULL, + forum_name VARCHAR(80) NOT NULL DEFAULT 'New forum', + forum_desc TEXT, + redirect_url VARCHAR(100), + moderators TEXT, + num_topics INTEGER NOT NULL DEFAULT 0, + num_posts INTEGER NOT NULL DEFAULT 0, + last_post INTEGER, + last_post_id INTEGER, + last_poster VARCHAR(200), + sort_by INTEGER NOT NULL DEFAULT 0, + disp_position INTEGER NOT NULL DEFAULT 0, + cat_id INTEGER NOT NULL DEFAULT 0, + PRIMARY KEY (id) + )"; + break; + } + + $db->query($sql) or error('Unable to create table '.$db_prefix.'forums. Please check your settings and try again.', __FILE__, __LINE__, $db->error()); + + + + switch ($db_type) + { + case 'mysql': + case 'mysqli': + $sql = 'CREATE TABLE '.$db_prefix."groups ( + g_id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, + g_title VARCHAR(50) NOT NULL DEFAULT '', + g_user_title VARCHAR(50), + g_read_board TINYINT(1) NOT NULL DEFAULT 1, + g_post_replies TINYINT(1) NOT NULL DEFAULT 1, + g_post_topics TINYINT(1) NOT NULL DEFAULT 1, + g_post_polls TINYINT(1) NOT NULL DEFAULT 1, + g_edit_posts TINYINT(1) NOT NULL DEFAULT 1, + g_delete_posts TINYINT(1) NOT NULL DEFAULT 1, + g_delete_topics TINYINT(1) NOT NULL DEFAULT 1, + g_set_title TINYINT(1) NOT NULL DEFAULT 1, + g_search TINYINT(1) NOT NULL DEFAULT 1, + g_search_users TINYINT(1) NOT NULL DEFAULT 1, + g_edit_subjects_interval SMALLINT(6) NOT NULL DEFAULT 300, + g_post_flood SMALLINT(6) NOT NULL DEFAULT 30, + g_search_flood SMALLINT(6) NOT NULL DEFAULT 30, + PRIMARY KEY (g_id) + ) TYPE=MyISAM;"; + break; + + case 'pgsql': + $sql = 'CREATE TABLE '.$db_prefix."groups ( + g_id SERIAL, + g_title VARCHAR(50) NOT NULL DEFAULT '', + g_user_title VARCHAR(50), + g_read_board SMALLINT NOT NULL DEFAULT 1, + g_post_replies SMALLINT NOT NULL DEFAULT 1, + g_post_topics SMALLINT NOT NULL DEFAULT 1, + g_post_polls SMALLINT NOT NULL DEFAULT 1, + g_edit_posts SMALLINT NOT NULL DEFAULT 1, + g_delete_posts SMALLINT NOT NULL DEFAULT 1, + g_delete_topics SMALLINT NOT NULL DEFAULT 1, + g_set_title SMALLINT NOT NULL DEFAULT 1, + g_search SMALLINT NOT NULL DEFAULT 1, + g_search_users SMALLINT NOT NULL DEFAULT 1, + g_edit_subjects_interval SMALLINT NOT NULL DEFAULT 300, + g_post_flood SMALLINT NOT NULL DEFAULT 30, + g_search_flood SMALLINT NOT NULL DEFAULT 30, + PRIMARY KEY (g_id) + )"; + break; + + case 'sqlite': + $sql = 'CREATE TABLE '.$db_prefix."groups ( + g_id INTEGER NOT NULL, + g_title VARCHAR(50) NOT NULL DEFAULT '', + g_user_title VARCHAR(50), + g_read_board INTEGER NOT NULL DEFAULT 1, + g_post_replies INTEGER NOT NULL DEFAULT 1, + g_post_topics INTEGER NOT NULL DEFAULT 1, + g_post_polls INTEGER NOT NULL DEFAULT 1, + g_edit_posts INTEGER NOT NULL DEFAULT 1, + g_delete_posts INTEGER NOT NULL DEFAULT 1, + g_delete_topics INTEGER NOT NULL DEFAULT 1, + g_set_title INTEGER NOT NULL DEFAULT 1, + g_search INTEGER NOT NULL DEFAULT 1, + g_search_users INTEGER NOT NULL DEFAULT 1, + g_edit_subjects_interval INTEGER NOT NULL DEFAULT 300, + g_post_flood INTEGER NOT NULL DEFAULT 30, + g_search_flood INTEGER NOT NULL DEFAULT 30, + PRIMARY KEY (g_id) + )"; + break; + } + + $db->query($sql) or error('Unable to create table '.$db_prefix.'groups. Please check your settings and try again.', __FILE__, __LINE__, $db->error()); + + + + switch ($db_type) + { + case 'mysql': + case 'mysqli': + $sql = 'CREATE TABLE '.$db_prefix."online ( + user_id INT(10) UNSIGNED NOT NULL DEFAULT 1, + ident VARCHAR(200) NOT NULL DEFAULT '', + logged INT(10) UNSIGNED NOT NULL DEFAULT 0, + idle TINYINT(1) NOT NULL DEFAULT 0 + ) TYPE=HEAP;"; + break; + + case 'pgsql': + $sql = 'CREATE TABLE '.$db_prefix."online ( + user_id INT NOT NULL DEFAULT 1, + ident VARCHAR(200) NOT NULL DEFAULT '', + logged INT NOT NULL DEFAULT 0, + idle SMALLINT NOT NULL DEFAULT 0 + )"; + break; + + case 'sqlite': + $sql = 'CREATE TABLE '.$db_prefix."online ( + user_id INTEGER NOT NULL DEFAULT 1, + ident VARCHAR(200) NOT NULL DEFAULT '', + logged INTEGER NOT NULL DEFAULT 0, + idle INTEGER NOT NULL DEFAULT 0 + )"; + break; + } + + $db->query($sql) or error('Unable to create table '.$db_prefix.'online. Please check your settings and try again.', __FILE__, __LINE__, $db->error()); + + + + switch ($db_type) + { + case 'mysql': + case 'mysqli': + $sql = 'CREATE TABLE '.$db_prefix."posts ( + id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, + poster VARCHAR(200) NOT NULL DEFAULT '', + poster_id INT(10) UNSIGNED NOT NULL DEFAULT 1, + poster_ip VARCHAR(15), + poster_email VARCHAR(50), + message TEXT, + hide_smilies TINYINT(1) NOT NULL DEFAULT 0, + posted INT(10) UNSIGNED NOT NULL DEFAULT 0, + edited INT(10) UNSIGNED, + edited_by VARCHAR(200), + topic_id INT(10) UNSIGNED NOT NULL DEFAULT 0, + PRIMARY KEY (id) + ) TYPE=MyISAM;"; + break; + + case 'pgsql': + $sql = 'CREATE TABLE '.$db_prefix."posts ( + id SERIAL, + poster VARCHAR(200) NOT NULL DEFAULT '', + poster_id INT NOT NULL DEFAULT 1, + poster_ip VARCHAR(15), + poster_email VARCHAR(50), + message TEXT, + hide_smilies SMALLINT NOT NULL DEFAULT 0, + posted INT NOT NULL DEFAULT 0, + edited INT, + edited_by VARCHAR(200), + topic_id INT NOT NULL DEFAULT 0, + PRIMARY KEY (id) + )"; + break; + + case 'sqlite': + $sql = 'CREATE TABLE '.$db_prefix."posts ( + id INTEGER NOT NULL, + poster VARCHAR(200) NOT NULL DEFAULT '', + poster_id INTEGER NOT NULL DEFAULT 1, + poster_ip VARCHAR(15), + poster_email VARCHAR(50), + message TEXT, + hide_smilies INTEGER NOT NULL DEFAULT 0, + posted INTEGER NOT NULL DEFAULT 0, + edited INTEGER, + edited_by VARCHAR(200), + topic_id INTEGER NOT NULL DEFAULT 0, + PRIMARY KEY (id) + )"; + break; + } + + $db->query($sql) or error('Unable to create table '.$db_prefix.'posts. Please check your settings and try again.', __FILE__, __LINE__, $db->error()); + + + + switch ($db_type) + { + case 'mysql': + case 'mysqli': + $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) + ) TYPE=MyISAM;"; + 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; + + case 'sqlite': + $sql = 'CREATE TABLE '.$db_prefix."ranks ( + id INTEGER NOT NULL, + rank VARCHAR(50) NOT NULL DEFAULT '', + min_posts INTEGER NOT NULL DEFAULT 0, + PRIMARY KEY (id) + )"; + break; + } + + $db->query($sql) or error('Unable to create table '.$db_prefix.'titles. Please check your settings and try again.', __FILE__, __LINE__, $db->error()); + + + + switch ($db_type) + { + case 'mysql': + case 'mysqli': + $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, + zapped INT(10) UNSIGNED, + zapped_by INT(10) UNSIGNED, + PRIMARY KEY (id) + ) TYPE=MyISAM;"; + 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, + zapped INT, + zapped_by INT, + PRIMARY KEY (id) + )"; + break; + + case 'sqlite': + $sql = 'CREATE TABLE '.$db_prefix."reports ( + id INTEGER NOT NULL, + post_id INTEGER NOT NULL DEFAULT 0, + topic_id INTEGER NOT NULL DEFAULT 0, + forum_id INTEGER NOT NULL DEFAULT 0, + reported_by INTEGER NOT NULL DEFAULT 0, + created INTEGER NOT NULL DEFAULT 0, + message TEXT, + zapped INTEGER, + zapped_by INTEGER, + PRIMARY KEY (id) + )"; + break; + } + + $db->query($sql) or error('Unable to create table '.$db_prefix.'reports. Please check your settings and try again.', __FILE__, __LINE__, $db->error()); + + + + switch ($db_type) + { + case 'mysql': + case 'mysqli': + $sql = 'CREATE TABLE '.$db_prefix."search_cache ( + id INT(10) UNSIGNED NOT NULL DEFAULT 0, + ident VARCHAR(200) NOT NULL DEFAULT '', + search_data TEXT, + PRIMARY KEY (id) + ) TYPE=MyISAM;"; + break; + + case 'pgsql': + $sql = 'CREATE TABLE '.$db_prefix."search_cache ( + id INT NOT NULL DEFAULT 0, + ident VARCHAR(200) NOT NULL DEFAULT '', + search_data TEXT, + PRIMARY KEY (id) + )"; + break; + + case 'sqlite': + $sql = 'CREATE TABLE '.$db_prefix."search_cache ( + id INTEGER NOT NULL DEFAULT 0, + ident VARCHAR(200) NOT NULL DEFAULT '', + search_data TEXT, + PRIMARY KEY (id) + )"; + break; + } + + $db->query($sql) or error('Unable to create table '.$db_prefix.'search_cache. Please check your settings and try again.', __FILE__, __LINE__, $db->error()); + + + + switch ($db_type) + { + case 'mysql': + case 'mysqli': + $sql = 'CREATE TABLE '.$db_prefix."search_matches ( + post_id INT(10) UNSIGNED NOT NULL DEFAULT 0, + word_id MEDIUMINT(8) UNSIGNED NOT NULL DEFAULT 0, + subject_match TINYINT(1) NOT NULL DEFAULT 0 + ) TYPE=MyISAM;"; + 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; + + case 'sqlite': + $sql = 'CREATE TABLE '.$db_prefix."search_matches ( + post_id INTEGER NOT NULL DEFAULT 0, + word_id INTEGER NOT NULL DEFAULT 0, + subject_match INTEGER NOT NULL DEFAULT 0 + )"; + break; + } + + $db->query($sql) or error('Unable to create table '.$db_prefix.'search_matches. Please check your settings and try again.', __FILE__, __LINE__, $db->error()); + + + + switch ($db_type) + { + case 'mysql': + case 'mysqli': + $sql = 'CREATE TABLE '.$db_prefix."search_words ( + id MEDIUMINT(8) UNSIGNED NOT NULL AUTO_INCREMENT, + word VARCHAR(20) BINARY NOT NULL DEFAULT '', + PRIMARY KEY (word), + KEY ".$db_prefix."search_words_id_idx (id) + ) TYPE=MyISAM;"; + break; + + case 'pgsql': + $sql = 'CREATE TABLE '.$db_prefix."search_words ( + id SERIAL, + word VARCHAR(20) NOT NULL DEFAULT '', + PRIMARY KEY (word) + )"; + break; + + case 'sqlite': + $sql = 'CREATE TABLE '.$db_prefix."search_words ( + id INTEGER NOT NULL, + word VARCHAR(20) NOT NULL DEFAULT '', + PRIMARY KEY (id), + UNIQUE (word) + )"; + break; + } + + $db->query($sql) or error('Unable to create table '.$db_prefix.'search_words. Please check your settings and try again.', __FILE__, __LINE__, $db->error()); + + + + switch ($db_type) + { + case 'mysql': + case 'mysqli': + $sql = 'CREATE TABLE '.$db_prefix."subscriptions ( + user_id INT(10) UNSIGNED NOT NULL DEFAULT 0, + topic_id INT(10) UNSIGNED NOT NULL DEFAULT 0, + PRIMARY KEY (user_id, topic_id) + ) TYPE=MyISAM;"; + break; + + case 'pgsql': + $sql = 'CREATE TABLE '.$db_prefix."subscriptions ( + user_id INT NOT NULL DEFAULT 0, + topic_id INT NOT NULL DEFAULT 0, + PRIMARY KEY (user_id, topic_id) + )"; + break; + + case 'sqlite': + $sql = 'CREATE TABLE '.$db_prefix."subscriptions ( + user_id INTEGER NOT NULL DEFAULT 0, + topic_id INTEGER NOT NULL DEFAULT 0, + PRIMARY KEY (user_id, topic_id) + )"; + break; + } + + $db->query($sql) or error('Unable to create table '.$db_prefix.'subscriptions. Please check your settings and try again.', __FILE__, __LINE__, $db->error()); + + + + switch ($db_type) + { + case 'mysql': + case 'mysqli': + $sql = 'CREATE TABLE '.$db_prefix."topics ( + id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, + poster VARCHAR(200) NOT NULL DEFAULT '', + subject VARCHAR(255) 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(200), + 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, + forum_id INT(10) UNSIGNED NOT NULL DEFAULT 0, + PRIMARY KEY (id) + ) TYPE=MyISAM;"; + break; + + case 'pgsql': + $sql = 'CREATE TABLE '.$db_prefix."topics ( + id SERIAL, + poster VARCHAR(200) NOT NULL DEFAULT '', + subject VARCHAR(255) 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(200), + 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, + forum_id INT NOT NULL DEFAULT 0, + PRIMARY KEY (id) + )"; + break; + + case 'sqlite': + $sql = 'CREATE TABLE '.$db_prefix."topics ( + id INTEGER NOT NULL, + poster VARCHAR(200) NOT NULL DEFAULT '', + subject VARCHAR(255) NOT NULL DEFAULT '', + posted INTEGER NOT NULL DEFAULT 0, + last_post INTEGER NOT NULL DEFAULT 0, + last_post_id INTEGER NOT NULL DEFAULT 0, + last_poster VARCHAR(200), + num_views INTEGER NOT NULL DEFAULT 0, + num_replies INTEGER NOT NULL DEFAULT 0, + closed INTEGER NOT NULL DEFAULT 0, + sticky INTEGER NOT NULL DEFAULT 0, + moved_to INTEGER, + forum_id INTEGER NOT NULL DEFAULT 0, + PRIMARY KEY (id) + )"; + break; + } + + $db->query($sql) or error('Unable to create table '.$db_prefix.'topics. Please check your settings and try again.', __FILE__, __LINE__, $db->error()); + + + + switch ($db_type) + { + case 'mysql': + case 'mysqli': + $sql = 'CREATE TABLE '.$db_prefix."users ( + id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, + group_id INT(10) UNSIGNED NOT NULL DEFAULT 4, + username VARCHAR(200) NOT NULL DEFAULT '', + password VARCHAR(40) NOT NULL DEFAULT '', + email VARCHAR(50) NOT NULL DEFAULT '', + title VARCHAR(50), + realname VARCHAR(40), + url VARCHAR(100), + jabber VARCHAR(75), + icq VARCHAR(12), + msn VARCHAR(50), + aim VARCHAR(30), + yahoo VARCHAR(30), + location VARCHAR(30), + use_avatar TINYINT(1) NOT NULL DEFAULT 0, + signature TEXT, + disp_topics TINYINT(3) UNSIGNED, + disp_posts TINYINT(3) UNSIGNED, + email_setting TINYINT(1) NOT NULL DEFAULT 1, + save_pass TINYINT(1) NOT NULL DEFAULT 1, + notify_with_post TINYINT(1) NOT NULL DEFAULT 0, + show_smilies TINYINT(1) NOT NULL DEFAULT 1, + show_img TINYINT(1) NOT NULL DEFAULT 1, + show_img_sig TINYINT(1) NOT NULL DEFAULT 1, + show_avatars TINYINT(1) NOT NULL DEFAULT 1, + show_sig TINYINT(1) NOT NULL DEFAULT 1, + timezone FLOAT NOT NULL DEFAULT 0, + language VARCHAR(25) NOT NULL DEFAULT 'English', + style VARCHAR(25) NOT NULL DEFAULT 'Oxygen', + num_posts INT(10) UNSIGNED NOT NULL DEFAULT 0, + last_post INT(10) UNSIGNED, + registered INT(10) UNSIGNED NOT NULL DEFAULT 0, + registration_ip VARCHAR(15) NOT NULL DEFAULT '0.0.0.0', + last_visit INT(10) UNSIGNED NOT NULL DEFAULT 0, + admin_note VARCHAR(30), + activate_string VARCHAR(50), + activate_key VARCHAR(8), + PRIMARY KEY (id) + ) TYPE=MyISAM;"; + break; + + case 'pgsql': + $sql = 'CREATE TABLE '.$db_prefix."users ( + id SERIAL, + group_id INT NOT NULL DEFAULT 4, + username VARCHAR(200) NOT NULL DEFAULT '', + password VARCHAR(40) NOT NULL DEFAULT '', + email VARCHAR(50) NOT NULL DEFAULT '', + title VARCHAR(50), + realname VARCHAR(40), + url VARCHAR(100), + jabber VARCHAR(75), + icq VARCHAR(12), + msn VARCHAR(50), + aim VARCHAR(30), + yahoo VARCHAR(30), + location VARCHAR(30), + use_avatar SMALLINT NOT NULL DEFAULT 0, + signature TEXT, + disp_topics SMALLINT, + disp_posts SMALLINT, + email_setting SMALLINT NOT NULL DEFAULT 1, + save_pass SMALLINT NOT NULL DEFAULT 1, + notify_with_post SMALLINT NOT NULL DEFAULT 0, + show_smilies SMALLINT NOT NULL DEFAULT 1, + show_img SMALLINT NOT NULL DEFAULT 1, + show_img_sig SMALLINT NOT NULL DEFAULT 1, + show_avatars SMALLINT NOT NULL DEFAULT 1, + show_sig SMALLINT NOT NULL DEFAULT 1, + timezone REAL NOT NULL DEFAULT 0, + language VARCHAR(25) NOT NULL DEFAULT 'English', + style VARCHAR(25) NOT NULL DEFAULT 'Oxygen', + num_posts INT NOT NULL DEFAULT 0, + last_post INT, + registered INT NOT NULL DEFAULT 0, + registration_ip VARCHAR(15) NOT NULL DEFAULT '0.0.0.0', + last_visit INT NOT NULL DEFAULT 0, + admin_note VARCHAR(30), + activate_string VARCHAR(50), + activate_key VARCHAR(8), + PRIMARY KEY (id) + )"; + break; + + case 'sqlite': + $sql = 'CREATE TABLE '.$db_prefix."users ( + id INTEGER NOT NULL, + group_id INTEGER NOT NULL DEFAULT 4, + username VARCHAR(200) NOT NULL DEFAULT '', + password VARCHAR(40) NOT NULL DEFAULT '', + email VARCHAR(50) NOT NULL DEFAULT '', + title VARCHAR(50), + realname VARCHAR(40), + url VARCHAR(100), + jabber VARCHAR(75), + icq VARCHAR(12), + msn VARCHAR(50), + aim VARCHAR(30), + yahoo VARCHAR(30), + location VARCHAR(30), + use_avatar INTEGER NOT NULL DEFAULT 0, + signature TEXT, + disp_topics INTEGER, + disp_posts INTEGER, + email_setting INTEGER NOT NULL DEFAULT 1, + save_pass INTEGER NOT NULL DEFAULT 1, + notify_with_post INTEGER NOT NULL DEFAULT 0, + show_smilies INTEGER NOT NULL DEFAULT 1, + show_img INTEGER NOT NULL DEFAULT 1, + show_img_sig INTEGER NOT NULL DEFAULT 1, + show_avatars INTEGER NOT NULL DEFAULT 1, + show_sig INTEGER NOT NULL DEFAULT 1, + timezone FLOAT NOT NULL DEFAULT 0, + language VARCHAR(25) NOT NULL DEFAULT 'English', + style VARCHAR(25) NOT NULL DEFAULT 'Oxygen', + num_posts INTEGER NOT NULL DEFAULT 0, + last_post INTEGER, + registered INTEGER NOT NULL DEFAULT 0, + registration_ip VARCHAR(15) NOT NULL DEFAULT '0.0.0.0', + last_visit INTEGER NOT NULL DEFAULT 0, + admin_note VARCHAR(30), + activate_string VARCHAR(50), + activate_key VARCHAR(8), + PRIMARY KEY (id) + )"; + break; + } + + $db->query($sql) or error('Unable to create table '.$db_prefix.'users. Please check your settings and try again.', __FILE__, __LINE__, $db->error()); + + + // Add some indexes + switch ($db_type) + { + case 'mysql': + case 'mysqli': + // We use MySQL's ALTER TABLE ... ADD INDEX syntax instead of CREATE INDEX to avoid problems with users lacking the INDEX privilege + $queries[] = 'ALTER TABLE '.$db_prefix.'online ADD UNIQUE INDEX '.$db_prefix.'online_user_id_ident_idx(user_id,ident)'; + $queries[] = 'ALTER TABLE '.$db_prefix.'online ADD INDEX '.$db_prefix.'online_user_id_idx(user_id)'; + $queries[] = 'ALTER TABLE '.$db_prefix.'posts ADD INDEX '.$db_prefix.'posts_topic_id_idx(topic_id)'; + $queries[] = 'ALTER TABLE '.$db_prefix.'posts ADD INDEX '.$db_prefix.'posts_multi_idx(poster_id, topic_id)'; + $queries[] = 'ALTER TABLE '.$db_prefix.'reports ADD INDEX '.$db_prefix.'reports_zapped_idx(zapped)'; + $queries[] = 'ALTER TABLE '.$db_prefix.'search_matches ADD INDEX '.$db_prefix.'search_matches_word_id_idx(word_id)'; + $queries[] = 'ALTER TABLE '.$db_prefix.'search_matches ADD INDEX '.$db_prefix.'search_matches_post_id_idx(post_id)'; + $queries[] = 'ALTER TABLE '.$db_prefix.'topics ADD INDEX '.$db_prefix.'topics_forum_id_idx(forum_id)'; + $queries[] = 'ALTER TABLE '.$db_prefix.'topics ADD INDEX '.$db_prefix.'topics_moved_to_idx(moved_to)'; + $queries[] = 'ALTER TABLE '.$db_prefix.'users ADD INDEX '.$db_prefix.'users_registered_idx(registered)'; + $queries[] = 'ALTER TABLE '.$db_prefix.'search_cache ADD INDEX '.$db_prefix.'search_cache_ident_idx(ident(8))'; + $queries[] = 'ALTER TABLE '.$db_prefix.'users ADD INDEX '.$db_prefix.'users_username_idx(username(8))'; + break; + + default: + $queries[] = 'CREATE INDEX '.$db_prefix.'online_user_id_idx ON '.$db_prefix.'online(user_id)'; + $queries[] = 'CREATE INDEX '.$db_prefix.'posts_topic_id_idx ON '.$db_prefix.'posts(topic_id)'; + $queries[] = 'CREATE INDEX '.$db_prefix.'posts_multi_idx ON '.$db_prefix.'posts(poster_id, topic_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.'topics_forum_id_idx ON '.$db_prefix.'topics(forum_id)'; + $queries[] = 'CREATE INDEX '.$db_prefix.'topics_moved_to_idx ON '.$db_prefix.'topics(moved_to)'; + $queries[] = 'CREATE INDEX '.$db_prefix.'users_registered_idx ON '.$db_prefix.'users(registered)'; + $queries[] = 'CREATE INDEX '.$db_prefix.'users_username_idx ON '.$db_prefix.'users(username)'; + $queries[] = 'CREATE INDEX '.$db_prefix.'search_cache_ident_idx ON '.$db_prefix.'search_cache(ident)'; + $queries[] = 'CREATE INDEX '.$db_prefix.'search_words_id_idx ON '.$db_prefix.'search_words(id)'; + break; + } + + @reset($queries); + while (list(, $sql) = @each($queries)) + $db->query($sql) or error('Unable to create indexes. Please check your configuration and try again.', __FILE__, __LINE__, $db->error()); + + + + $now = time(); + + // Insert the four preset groups + $db->query('INSERT INTO '.$db->prefix."groups (g_title, g_user_title, g_read_board, g_post_replies, g_post_topics, g_post_polls, g_edit_posts, g_delete_posts, g_delete_topics, g_set_title, g_search, g_search_users, g_edit_subjects_interval, g_post_flood, g_search_flood) VALUES('Administrators', 'Administrator', 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0)") or error('Unable to add group', __FILE__, __LINE__, $db->error()); + $db->query('INSERT INTO '.$db->prefix."groups (g_title, g_user_title, g_read_board, g_post_replies, g_post_topics, g_post_polls, g_edit_posts, g_delete_posts, g_delete_topics, g_set_title, g_search, g_search_users, g_edit_subjects_interval, g_post_flood, g_search_flood) VALUES('Moderators', 'Moderator', 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0)") or error('Unable to add group', __FILE__, __LINE__, $db->error()); + $db->query('INSERT INTO '.$db->prefix."groups (g_title, g_user_title, g_read_board, g_post_replies, g_post_topics, g_post_polls, g_edit_posts, g_delete_posts, g_delete_topics, g_set_title, g_search, g_search_users, g_edit_subjects_interval, g_post_flood, g_search_flood) VALUES('Guest', NULL, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0)") or error('Unable to add group', __FILE__, __LINE__, $db->error()); + $db->query('INSERT INTO '.$db->prefix."groups (g_title, g_user_title, g_read_board, g_post_replies, g_post_topics, g_post_polls, g_edit_posts, g_delete_posts, g_delete_topics, g_set_title, g_search, g_search_users, g_edit_subjects_interval, g_post_flood, g_search_flood) VALUES('Members', NULL, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 300, 60, 30)") or error('Unable to add group', __FILE__, __LINE__, $db->error()); + + // Insert guest and first admin user + $db->query('INSERT INTO '.$db_prefix."users (group_id, username, password, email) VALUES(3, 'Guest', 'Guest', 'Guest')") + or error('Unable to add guest user. Please check your configuration and try again.'); + + $db->query('INSERT INTO '.$db_prefix."users (group_id, username, password, email, num_posts, last_post, registered, registration_ip, last_visit) VALUES(1, '".$db->escape($username)."', '".pun_hash($password1)."', '$email', 1, ".$now.", ".$now.", '127.0.0.1', ".$now.')') + or error('Unable to add administrator user. Please check your configuration and try again.'); + + // Insert config data + $config = array( + 'o_cur_version' => "'$punbb_version'", + 'o_board_title' => "'My PunBB forum'", + 'o_board_desc' => "'Unfortunately no one can be told what PunBB is - you have to see it for yourself.'", + 'o_server_timezone' => "'0'", + 'o_time_format' => "'H:i:s'", + 'o_date_format' => "'Y-m-d'", + 'o_timeout_visit' => "'600'", + 'o_timeout_online' => "'300'", + 'o_redirect_delay' => "'1'", + 'o_show_version' => "'0'", + 'o_show_user_info' => "'1'", + 'o_show_post_count' => "'1'", + 'o_smilies' => "'1'", + 'o_smilies_sig' => "'1'", + 'o_make_links' => "'1'", + 'o_default_lang' => "'English'", + 'o_default_style' => "'Oxygen'", + 'o_default_user_group' => "'4'", + 'o_topic_review' => "'15'", + 'o_disp_topics_default' => "'30'", + 'o_disp_posts_default' => "'25'", + 'o_indent_num_spaces' => "'4'", + 'o_quickpost' => "'1'", + 'o_users_online' => "'1'", + 'o_censoring' => "'0'", + 'o_ranks' => "'1'", + 'o_show_dot' => "'0'", + 'o_quickjump' => "'1'", + 'o_gzip' => "'0'", + 'o_additional_navlinks' => "''", + 'o_report_method' => "'0'", + 'o_regs_report' => "'0'", + 'o_mailing_list' => "'$email'", + 'o_avatars' => "'1'", + 'o_avatars_dir' => "'img/avatars'", + 'o_avatars_width' => "'60'", + 'o_avatars_height' => "'60'", + 'o_avatars_size' => "'10240'", + 'o_search_all_forums' => "'1'", + 'o_base_url' => "'$base_url'", + 'o_admin_email' => "'$email'", + 'o_webmaster_email' => "'$email'", + 'o_subscriptions' => "'1'", + 'o_smtp_host' => "NULL", + 'o_smtp_user' => "NULL", + 'o_smtp_pass' => "NULL", + 'o_regs_allow' => "'1'", + 'o_regs_verify' => "'0'", + 'o_announcement' => "'0'", + 'o_announcement_message' => "'Enter your announcement here.'", + 'o_rules' => "'0'", + 'o_rules_message' => "'Enter your rules here.'", + 'o_maintenance' => "'0'", + 'o_maintenance_message' => "'The forums are temporarily down for maintenance. Please try again in a few minutes.
    \\n
    \\n/Administrator'", + 'p_mod_edit_users' => "'1'", + 'p_mod_rename_users' => "'0'", + 'p_mod_change_passwords' => "'0'", + 'p_mod_ban_users' => "'0'", + 'p_message_bbcode' => "'1'", + 'p_message_img_tag' => "'1'", + 'p_message_all_caps' => "'1'", + 'p_subject_all_caps' => "'1'", + 'p_sig_all_caps' => "'1'", + 'p_sig_bbcode' => "'1'", + 'p_sig_img_tag' => "'0'", + 'p_sig_length' => "'400'", + 'p_sig_lines' => "'4'", + 'p_allow_banned_email' => "'1'", + 'p_allow_dupe_email' => "'0'", + 'p_force_guest_email' => "'1'" + ); + + while (list($conf_name, $conf_value) = @each($config)) + { + $db->query('INSERT INTO '.$db_prefix."config (conf_name, conf_value) VALUES('$conf_name', $conf_value)") + or error('Unable to insert into table '.$db_prefix.'config. Please check your configuration and try again.'); + } + + // Insert some other default data + $db->query('INSERT INTO '.$db_prefix."categories (cat_name, disp_position) VALUES('Test category', 1)") + or error('Unable to insert into table '.$db_prefix.'categories. Please check your configuration and try again.'); + + $db->query('INSERT INTO '.$db_prefix."forums (forum_name, forum_desc, num_topics, num_posts, last_post, last_post_id, last_poster, disp_position, cat_id) VALUES('Test forum', 'This is just a test forum', 1, 1, ".$now.", 1, '".$db->escape($username)."', 1, 1)") + or error('Unable to insert into table '.$db_prefix.'forums. Please check your configuration and try again.'); + + $db->query('INSERT INTO '.$db_prefix."topics (poster, subject, posted, last_post, last_post_id, last_poster, forum_id) VALUES('".$db->escape($username)."', 'Test post', ".$now.", ".$now.", 1, '".$db->escape($username)."', 1)") + or error('Unable to insert into table '.$db_prefix.'topics. Please check your configuration and try again.'); + + $db->query('INSERT INTO '.$db_prefix."posts (poster, poster_id, poster_ip, message, posted, topic_id) VALUES('".$db->escape($username)."', 2, '127.0.0.1', '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 error('Unable to insert into table '.$db_prefix.'posts. Please check your configuration and try again.'); + + $db->query('INSERT INTO '.$db_prefix."ranks (rank, min_posts) VALUES('New member', 0)") + or error('Unable to insert into table '.$db_prefix.'ranks. Please check your configuration and try again.'); + + $db->query('INSERT INTO '.$db_prefix."ranks (rank, min_posts) VALUES('Member', 10)") + or error('Unable to insert into table '.$db_prefix.'ranks. Please check your configuration and try again.'); + + + if ($db_type == 'pgsql' || $db_type == 'sqlite') + $db->end_transaction(); + + + + $alerts = ''; + // Check if the cache directory is writable + if (!@is_writable('./cache/')) + $alerts .= '

    The cache directory is currently not writable! In order for PunBB to function properly, the directory named cache must be writable by PHP. Use chmod to set the appropriate directory permissions. If in doubt, chmod to 0777.

    '; + + // Check if default avatar directory is writable + if (!@is_writable('./img/avatars/')) + $alerts .= '

    The avatar directory is currently not writable! If you want users to be able to upload their own avatar images you must see to it that the directory named img/avatars is writable by PHP. You can later choose to save avatar images in a different directory (see Admin/Options). Use chmod to set the appropriate directory permissions. If in doubt, chmod to 0777.

    '; + + + /// 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. Make sure there are no linebreaks or spaces before <?php. You can later edit config.php if you reconfigure your setup (e.g. change the database password or ).

    + +
    +
    + Copy contents to config.php +
    + +
    +
    +
    +
    +
    +

    Once you have created config.php with the contents above, PunBB is installed!

    +

    Go to forum index

    +
    +
    +
    +
    +
    + +
    +
    + + + + 'ltr', // ltr (Left-To-Right) or rtl (Right-To-Left) +'lang_encoding' => 'iso-8859-1', +'lang_multibyte' => false, + +// Notices +'Bad request' => 'Bad request. The link you followed is incorrect or outdated.', +'No view' => 'You do not have permission to view these forums.', +'No permission' => 'You do not have permission to access this page.', +'Bad referrer' => 'Bad HTTP_REFERER. You were referred to this page from an unauthorized source. If the problem persists please make sure that \'Base URL\' is correctly set in Admin/Options and that you are visiting the forum by navigating to that URL. More information regarding the referrer check can be found in the PunBB documentation.', + +// Topic/forum indicators +'New icon' => 'There are new posts', +'Normal icon' => '', +'Closed icon' => 'This topic is closed', +'Redirect icon' => 'Redirected forum', + +// Miscellaneous +'Announcement' => 'Announcement', +'Options' => 'Options', +'Actions' => 'Actions', +'Submit' => 'Submit', // "name" of submit buttons +'Ban message' => 'You are banned from this forum.', +'Ban message 2' => 'The ban expires at the end of', +'Ban message 3' => 'The administrator or moderator that banned you left the following message:', +'Ban message 4' => 'Please direct any inquiries to the forum administrator at', +'Never' => 'Never', +'Today' => 'Today', +'Yesterday' => 'Yesterday', +'Info' => 'Info', // a common table header +'Go back' => 'Go back', +'Maintenance' => 'Maintenance', +'Redirecting' => 'Redirecting', +'Click redirect' => 'Click here if you do not want to wait any longer (or if your browser does not automatically forward you)', +'on' => 'on', // as in "BBCode is on" +'off' => 'off', +'Invalid 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 +'New posts' => 'New posts', // the link that leads to the first new post (use   for spaces) +'New posts info' => 'Go to the first new post in this topic.', // the popup text for new posts links +'Username' => 'Username', +'Password' => 'Password', +'E-mail' => 'E-mail', +'Send e-mail' => 'Send e-mail', +'Moderated by' => 'Moderated by', +'Registered' => 'Registered', +'Subject' => 'Subject', +'Message' => 'Message', +'Topic' => 'Topic', +'Forum' => 'Forum', +'Posts' => 'Posts', +'Replies' => 'Replies', +'Author' => 'Author', +'Pages' => 'Pages', +'BBCode' => 'BBCode', // You probably shouldn't change this +'img tag' => '[img] tag', +'Smilies' => 'Smilies', +'and' => 'and', +'Image link' => 'image', // This is displayed (i.e. ) instead of images when "Show images" is disabled in the profile +'wrote' => 'wrote', // For [quote]'s +'Code' => 'Code', // For [code]'s +'Mailer' => 'Mailer', // As in "MyForums Mailer" in the signature of outgoing e-mails +'Important information' => 'Important information', +'Write message legend' => 'Write your message and submit', + +// 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) +'Index' => 'Index', +'User list' => 'User list', +'Rules' => 'Rules', +'Search' => 'Search', +'Register' => 'Register', +'Login' => 'Login', +'Not logged in' => 'You are not logged in.', +'Profile' => 'Profile', +'Logout' => 'Logout', +'Logged in as' => 'Logged in as', +'Admin' => 'Administration', +'Last visit' => 'Last visit', +'Show new posts' => 'Show new posts since last visit', +'Mark all as read' => 'Mark all topics as read', +'Link separator' => '', // The text that separates links in the navigator + +// Stuff for the page footer +'Board footer' => 'Board footer', +'Search links' => 'Search links', +'Show recent posts' => 'Show recent posts', +'Show unanswered posts' => 'Show unanswered posts', +'Show your posts' => 'Show your posts', +'Show subscriptions' => 'Show your subscribed topics', +'Jump to' => 'Jump to', +'Go' => ' Go ', // submit button in forum jump +'Move topic' => 'Move topic', +'Open topic' => 'Open topic', +'Close topic' => 'Close topic', +'Unstick topic' => 'Unstick topic', +'Stick topic' => 'Stick topic', +'Moderate forum' => 'Moderate forum', +'Delete posts' => 'Delete multiple posts', +'Debug table' => 'Debug information', + +// For extern.php RSS feed +'RSS Desc Active' => 'The most recently active topics at', // board_title will be appended to this string +'RSS Desc New' => 'The newest topics at', // board_title will be appended to this string +'Posted' => 'Posted' // The date/time a topic was started + +); diff -r 000000000000 -r f9ffdbd96607 punbb/lang/English/delete.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/punbb/lang/English/delete.php Wed Jul 11 21:01:48 2007 -0400 @@ -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 -r 000000000000 -r f9ffdbd96607 punbb/lang/English/forum.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/punbb/lang/English/forum.php Wed Jul 11 21:01:48 2007 -0400 @@ -0,0 +1,12 @@ + 'Post new topic', +'Views' => 'Views', +'Moved' => 'Moved', +'Sticky' => 'Sticky', +'Empty forum' => 'Forum is empty.' + +); diff -r 000000000000 -r f9ffdbd96607 punbb/lang/English/help.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/punbb/lang/English/help.php Wed Jul 11 21:01:48 2007 -0400 @@ -0,0 +1,42 @@ + 'Help', +'produces' => 'produces', + +'BBCode info 1' => 'BBCode is a collection of formatting tags that are used to change the look of text in this forum. BBCode is based on the same principal as, and is very similar to, HTML. Below is a list of all the available BBCodes and instructions on how to use them.', +'BBCode info 2' => 'Administrators have the ability to enable or disable BBCode. You can tell if BBCode is enabled or disabled out in the left margin whenever you post a message or edit your signature.', + +'Text style' => 'Text style', +'Text style info' => 'The following tags change the appearance of text:', +'Bold text' => 'Bold text', +'Underlined text' => 'Underlined text', +'Italic text' => 'Italic text', +'Red text' => 'Red text', +'Blue text' => 'Blue text', + +'Links and images' => 'Links and images', +'Links info' => 'You can create links to other documents or to e-mail addresses 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' => 'Quotes', +'Quotes info' => 'If you want to quote someone, you should use the quote tag.', +'Quotes info 2' => 'If you don\'t want to quote anyone in particular, you can use the quote tag without specifying a name.', +'Quote text' => 'This is the text i want to quote.', +'produces quote box' => 'produces a quote box like this:', + +'Code' => 'Code', +'Code info' => 'When displaying source code you should make sure that you use the code tag. Text displayed with the code tag will use a monospaced font and will not be affected by other tags.', +'Code text' => 'This is some code.', +'produces code box' => 'produces a code box like this:', + +'Nested tags' => 'Nested tags', +'Nested tags info' => 'BBCode can be nested to create more advanced formatting. For example:', +'Bold, underlined text' => 'Bold, underlined text', + +'Smilies info' => 'If you like (and if it is enabled), the forum can convert a series of smilies to images representations of that smiley. This forum recognizes the following smilies and replaces them with images:' + +); diff -r 000000000000 -r f9ffdbd96607 punbb/lang/English/index.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/punbb/lang/English/index.html Wed Jul 11 21:01:48 2007 -0400 @@ -0,0 +1,8 @@ + + +. + + +. + + \ No newline at end of file diff -r 000000000000 -r f9ffdbd96607 punbb/lang/English/index.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/punbb/lang/English/index.php Wed Jul 11 21:01:48 2007 -0400 @@ -0,0 +1,21 @@ + 'Topics', +'Moderators' => 'Moderators', +'Link to' => 'Link to', // As in "Link to http://www.punbb.org/" +'Empty board' => 'Board is empty.', +'Newest user' => 'Newest registered user', +'Users online' => 'Registered users online', +'Guests online' => 'Guests online', +'No of users' => 'Total number of registered users', +'No of topics' => 'Total number of topics', +'No of posts' => 'Total number of posts', +'Online' => 'Online', // As in "Online: User A, User B etc." +'Board info' => 'Board information', +'Board stats' => 'Board statistics', +'User info' => 'User information' + +); diff -r 000000000000 -r f9ffdbd96607 punbb/lang/English/login.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/punbb/lang/English/login.php Wed Jul 11 21:01:48 2007 -0400 @@ -0,0 +1,22 @@ + '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 e-mail address', +'Request pass' => 'Request password', +'Request pass legend' => 'Enter the e-mail address with which you registered', +'Request pass info' => 'A new password together with a link to activate the new password will be sent to that address.', +'Not registered' => 'Not registered yet?', +'Login legend' => 'Enter your username and password below', +'Login info' => 'If you have not registered or have forgotten your password click on the appropriate link below.', + +// Forget password mail stuff +'Forget mail' => 'An e-mail has been sent to the specified address with instructions on how to change your password. If it does not arrive you can contact the forum administrator at' + +); diff -r 000000000000 -r f9ffdbd96607 punbb/lang/English/mail_templates/activate_email.tpl --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/punbb/lang/English/mail_templates/activate_email.tpl Wed Jul 11 21:01:48 2007 -0400 @@ -0,0 +1,12 @@ +Subject: Change e-mail address requested + +Hello , + +You have requested to have a new e-mail address assigned to your account in the discussion forum at . If you didn't request this or if you don't want to change your e-mail address you should just ignore this message. Only if you visit the activation page below will your e-mail address be changed. In order for the activation page to work, you must be logged in to the forum. + +To change your e-mail address, please visit the following page: + + +-- + +(Do not reply to this message) \ No newline at end of file diff -r 000000000000 -r f9ffdbd96607 punbb/lang/English/mail_templates/activate_password.tpl --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/punbb/lang/English/mail_templates/activate_password.tpl Wed Jul 11 21:01:48 2007 -0400 @@ -0,0 +1,14 @@ +Subject: New password requested + +Hello , + +You have requested to have a new password assigned to your account in the discussion forum at . If you didn't request this or if you don't want to change your password you should just ignore this message. Only if you visit the activation page below will your password be changed. + +Your new password is: + +To change your password, please visit the following page: + + +-- + +(Do not reply to this message) \ No newline at end of file diff -r 000000000000 -r f9ffdbd96607 punbb/lang/English/mail_templates/form_email.tpl --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/punbb/lang/English/mail_templates/form_email.tpl Wed Jul 11 21:01:48 2007 -0400 @@ -0,0 +1,13 @@ +Subject: + + from has sent you a message. You can reply to by replying to this e-mail. + +The message reads as follows: +----------------------------------------------------------------------- + + + +----------------------------------------------------------------------- + +-- + \ No newline at end of file diff -r 000000000000 -r f9ffdbd96607 punbb/lang/English/mail_templates/index.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/punbb/lang/English/mail_templates/index.html Wed Jul 11 21:01:48 2007 -0400 @@ -0,0 +1,8 @@ + + +. + + +. + + \ No newline at end of file diff -r 000000000000 -r f9ffdbd96607 punbb/lang/English/mail_templates/new_reply.tpl --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/punbb/lang/English/mail_templates/new_reply.tpl Wed Jul 11 21:01:48 2007 -0400 @@ -0,0 +1,11 @@ +Subject: Reply to topic: + + has replied to the topic to which you are subscribed. There may be more new replies, but this is the only notification you will receive until you visit the board again. + +The post is located at + +You can unsubscribe by going to + +-- + +(Do not reply to this message) \ No newline at end of file diff -r 000000000000 -r f9ffdbd96607 punbb/lang/English/mail_templates/new_reply_full.tpl --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/punbb/lang/English/mail_templates/new_reply_full.tpl Wed Jul 11 21:01:48 2007 -0400 @@ -0,0 +1,18 @@ +Subject: Reply to topic: + + has replied to the topic to which you are subscribed. There may be more new replies, but this is the only notification you will receive until you visit the board again. + +The message reads as follows: +----------------------------------------------------------------------- + + + +----------------------------------------------------------------------- + +The post is located at + +You can unsubscribe by going to + +-- + +(Do not reply to this message) \ No newline at end of file diff -r 000000000000 -r f9ffdbd96607 punbb/lang/English/mail_templates/welcome.tpl --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/punbb/lang/English/mail_templates/welcome.tpl Wed Jul 11 21:01:48 2007 -0400 @@ -0,0 +1,12 @@ +Subject: Welcome to ! + +Thank you for registering in the forums at . Your account details are: + +Username: +Password: + +Login at to activate the account. + +-- + +(Do not reply to this message) \ No newline at end of file diff -r 000000000000 -r f9ffdbd96607 punbb/lang/English/misc.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/punbb/lang/English/misc.php Wed Jul 11 21:01:48 2007 -0400 @@ -0,0 +1,67 @@ + 'All topics and forums have been marked as read. Redirecting …', + +// Send e-mail +'Form e-mail disabled' => 'The user you are trying to send an e-mail to has disabled form e-mail.', +'No e-mail subject' => 'You must enter a subject.', +'No e-mail message' => 'You must enter a message.', +'Too long e-mail message' => 'Messages cannot be longer than 65535 characters (64 KB).', +'E-mail sent redirect' => 'E-mail sent. Redirecting …', +'Send e-mail to' => 'Send e-mail to', +'E-mail subject' => 'Subject', +'E-mail message' => 'Message', +'E-mail disclosure note' => 'Please note that by using this form, your e-mail address will be disclosed to the recipient.', +'Write e-mail' => 'Write and submit your e-mail message', + +// Report +'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', + +// Subscriptions +'Already subscribed' => 'You are already subscribed to this topic.', +'Subscribe redirect' => 'Your subscription has been added. Redirecting …', +'Not subscribed' => 'You are not subscribed to this topic.', +'Unsubscribe redirect' => 'Your subscription has been removed. Redirecting …', + +// General forum and topic moderation +'Moderate' => 'Moderate', +'Select' => 'Select', // the header of a column of checkboxes +'Move' => 'Move', +'Delete' => 'Delete', + +// Moderate forum +'Open' => 'Open', +'Close' => 'Close', +'Move topic' => 'Move topic', +'Move topics' => 'Move topics', +'Move legend' => 'Select destination of move', +'Move to' => 'Move to', +'Leave redirect' => 'Leave redirect topic(s)', +'Move topic redirect' => 'Topic moved. Redirecting …', +'Move topics redirect' => 'Topics moved. Redirecting …', +'Confirm delete legend' => 'Please confirm deletion', +'Delete topics' => 'Delete topics', +'Delete topics comply' => 'Are you sure you want to delete the selected topics?', +'Delete topics redirect' => 'Topics deleted. Redirecting …', +'Open topic redirect' => 'Topic opened. Redirecting …', +'Open topics redirect' => 'Topics opened. Redirecting …', +'Close topic redirect' => 'Topic closed. Redirecting …', +'Close topics redirect' => 'Topics closed. Redirecting …', +'No topics selected' => 'You must select at least one topic for move/delete/open/close.', +'Stick topic redirect' => 'Topic sticked. Redirecting …', +'Unstick topic redirect' => 'Topic unsticked. Redirecting …', + +// Delete multiple posts in topic +'Delete posts' => 'Delete posts', +'Delete posts comply' => 'Are you sure you want to delete the selected posts?', +'Delete posts redirect' => 'Posts deleted. Redirecting …', +'No posts selected' => 'You must select at least one post to be deleted.' + +); diff -r 000000000000 -r f9ffdbd96607 punbb/lang/English/post.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/punbb/lang/English/post.php Wed Jul 11 21:01:48 2007 -0400 @@ -0,0 +1,33 @@ + 'Topics must contain a subject.', +'Too long subject' => 'Subjects cannot be longer than 70 characters.', +'No message' => 'You must enter a message.', +'Too long message' => 'Posts cannot be longer that 65535 characters (64 KB).', + +// Posting +'Post errors' => 'Post errors', +'Post errors info' => 'The following errors need to be corrected before the message can be posted:', +'Post preview' => 'Post preview', +'Guest name' => 'Name', // For guests (instead of Username) +'Post redirect' => 'Post entered. Redirecting …', +'Post a reply' => 'Post a reply', +'Post new topic' => 'Post new topic', +'Hide smilies' => 'Never show smilies as icons for this post', +'Subscribe' => 'Subscribe to this topic', +'Topic review' => 'Topic review (newest first)', +'Flood start' => 'At least', +'flood end' => 'seconds have to pass between posts. Please wait a little while and try posting again.', +'Preview' => 'Preview', // submit button to preview message + +// Edit post +'Edit post legend' => 'Edit the post and submit changes', +'Silent edit' => 'Silent edit (don\'t display "Edited by ..." in topic view)', +'Edit post' => 'Edit post', +'Edit redirect' => 'Post updated. Redirecting …' + +); diff -r 000000000000 -r f9ffdbd96607 punbb/lang/English/prof_reg.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/punbb/lang/English/prof_reg.php Wed Jul 11 21:01:48 2007 -0400 @@ -0,0 +1,39 @@ + 'Enter a valid e-mail address', +'E-mail legend 2' => 'Enter and confirm a valid e-mail address', +'Localisation legend' => 'Set your localisation options', +'Timezone' => 'Timezone', +'Timezone info' => 'For the forum to display times correctly you must select your local timezone.', +'Language' => 'Language', +'Language info' => 'You can choose which language you wish to use to view the forum.', +'E-mail setting info' => 'Select whether you want your e-mail address to be viewable to other users or not and if you want other users to be able to send you e-mail via the forum (form e-mail) or not.', +'E-mail setting 1' => 'Display your e-mail address.', +'E-mail setting 2' => 'Hide your e-mail address but allow form e-mail.', +'E-mail setting 3' => 'Hide your e-mail address and disallow form e-mail.', +'Privacy options legend' => 'Set your privacy options', +'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 visit the forum. You will be logged in automatically. Recommended.', +'Confirm pass' => 'Confirm password', + +'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 reserved chars' => 'Usernames may not contain all the characters \', " and [ or ] at once. Please choose another username.', +'Username BBCode' => 'Usernames may not contain any of the text formatting tags (BBCode) that the forum uses. Please choose another username.', +'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', +'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 -r 000000000000 -r f9ffdbd96607 punbb/lang/English/profile.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/punbb/lang/English/profile.php Wed Jul 11 21:01:48 2007 -0400 @@ -0,0 +1,144 @@ + 'Profile menu', +'Section essentials' => 'Essentials', +'Section personal' => 'Personal', +'Section messaging' => 'Messaging', +'Section personality' => 'Personality', +'Section display' => 'Display', +'Section privacy' => 'Privacy', +'Section admin' => 'Administration', + +// Miscellaneous +'Username and pass legend' => 'Enter your username and password', +'Personal details legend' => 'Enter your personal details', +'Contact details legend' => 'Enter your messaging details', +'Options display' => 'Set your display options', +'Options post' => 'Set your post viewing options', +'User activity' => 'User activity', +'Paginate info' => 'Enter the number of topics and posts you wish to view on each page.', + +// Password stuff +'Pass key bad' => 'The specified password activation key was incorrect or has expired. Please re-request a new password. If that fails, contact the forum administrator at', +'Pass updated' => 'Your password has been updated. You can now login with your new password.', +'Pass updated redirect' => 'Password updated. Redirecting …', +'Wrong pass' => 'Wrong old password.', +'Change pass' => 'Change password', +'Change pass legend' => 'Enter and confirm your new password', +'Old pass' => 'Old password', +'New pass' => 'New password', +'Confirm new pass' => 'Confirm new password', + +// 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 address. If that fails, contact the forum administrator at', +'E-mail updated' => 'Your e-mail address has been updated.', +'Activate e-mail sent' => 'An email has been sent to the specified address 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 legend' => 'Enter your new e-mail address', +'E-mail instructions' => 'An e-mail will be sent to your new address with an activation link. You must click the link in the e-mail you receive 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 tmp directory' => 'PHP was unable to save the uploaded file to a temporary location.', +'No file' => 'You did not select a file for upload.', +'Bad type' => 'The file you tried to upload is not of an allowed type. Allowed types are gif, jpeg and png.', +'Too wide or high' => 'The file you tried to upload is wider and/or higher than the maximum allowed', +'Too large' => 'The file you tried to upload is larger than the maximum allowed', +'pixels' => 'pixels', +'bytes' => 'bytes', +'Move failed' => 'The server was unable to save the uploaded file. Please contact the forum administrator at', +'Unknown failure' => 'An unknown error occurred. Please try again.', +'Avatar upload redirect' => 'Avatar uploaded. Redirecting …', +'Avatar deleted redirect' => 'Avatar deleted. Redirecting …', +'Avatar desc' => 'An avatar is a small image that will be displayed under your username in your posts. It must not be any bigger than', +'Upload avatar' => 'Upload avatar', +'Upload avatar legend' => 'Enter an avatar file to upload', +'Delete avatar' => 'Delete avatar', // only for admins +'File' => 'File', +'Upload' => 'Upload', // submit button + +// Form validation stuff +'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.', +'Unknown' => '(Unknown)', // This is displayed when a user hasn't filled out profile field (e.g. Location) +'Private' => '(Private)', // This is displayed when a user does not want to receive e-mails +'No avatar' => '(No avatar)', +'Show posts' => 'Show all posts', +'Realname' => 'Real name', +'Location' => 'Location', +'Website' => 'Website', +'Jabber' => 'Jabber', +'ICQ' => 'ICQ', +'MSN' => 'MSN Messenger', +'AOL IM' => 'AOL IM', +'Yahoo' => 'Yahoo! Messenger', +'Avatar' => 'Avatar', +'Signature' => 'Signature', +'Sig max length' => 'Max length', +'Sig max lines' => 'Max lines', +'Avatar legend' => 'Set your avatar display options', +'Avatar info' => 'An avatar is a small image that will be displayed with all your posts. You can upload an avatar by clicking the link below. 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 legend' => 'Compose your signature', +'Signature info' => 'A signature is a small piece of text that is attached to your posts. In it, you can enter just about anything you like. Perhaps you would like to enter your favourite quote or your star sign. It\'s up to you! In your signature you can use BBCode if it is allowed in this particular forum. You can see the features that are allowed/enabled listed below whenever you edit your signature.', +'Sig preview' => 'Current signature preview:', +'No sig' => 'No signature currently stored in profile.', +'Topics per page' => 'Topics', +'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', +'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.', +'Notify full' => 'Include post in subscription e-mails.', +'Notify full info' => 'With this enabled, a plain text version of the new post will be included in subscription notification e-mails.', +'Show smilies' => 'Show smilies as graphic icons', +'Show smilies info' => 'If you enable this option, small images will be displayed instead of text smilies.', +'Show images' => 'Show images in posts.', +'Show images info' => 'Disable this if you don\'t want to see images in posts (i.e. images displayed with the [img]-tag).', +'Show images sigs' => 'Show images in user signatures.', +'Show images sigs info' => 'Disable this if you don\'t want to see images in signatures (i.e. images displayed with the [img]-tag).', +'Show avatars' => 'Show user avatars in posts.', +'Show avatars info' => 'This option toggles whether user avatar images will be displayed in posts or not.', +'Show sigs' => 'Show user signatures.', +'Show sigs info' => 'Enable if you would like to see user signatures.', +'Style legend' => 'Select your preferred style', +'Style info' => 'If you like you can use a different visual style for this forum.', +'Admin note' => 'Admin note', +'Pagination legend' => 'Enter your pagination options', +'Post display legend' => 'Set your options for viewing posts', +'Post display info' => 'If you are on a slow connection, disabling these options, particularly showing images in posts and signatures, will make pages load faster.', +'Instructions' => 'When you update your profile, you will be redirected back to this page.', + +// Administration stuff +'Group membership legend' => 'Choose user group', +'Save' => 'Save', +'Set mods legend' => 'Set moderator access', +'Moderator in' => 'Moderator in', +'Moderator in info' => 'Choose what forums this user should be allowed to moderate. Note: This only applies to moderators. Administrators always have full permissions in all forums.', +'Update forums' => 'Update forums', +'Delete ban legend' => 'Delete (administrators only) or ban user', +'Delete user' => 'Delete user', +'Ban user' => 'Ban user', +'Confirm delete legend' => 'Important: read before deleting user', +'Confirm delete user' => 'Confirm delete user', +'Confirmation info' => 'Please confirm that you want to delete the user', // the username will be appended to this string +'Delete warning' => 'Warning! Deleted users and/or posts cannot be restored. If you choose not to delete the posts made by this user, the posts can only be deleted manually at a later time.', +'Delete posts' => 'Delete any posts and topics this user has made.', +'Delete' => 'Delete', // submit button (confirm user delete) +'User delete redirect' => 'User deleted. Redirecting …', +'Group membership redirect' => 'Group membership saved. Redirecting …', +'Update forums redirect' => 'Forum moderator rights updated. Redirecting …', +'Ban redirect' => 'Redirecting …' + +); diff -r 000000000000 -r f9ffdbd96607 punbb/lang/English/register.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/punbb/lang/English/register.php Wed Jul 11 21:01:48 2007 -0400 @@ -0,0 +1,35 @@ + 'This forum is not accepting new registrations.', +'Reg cancel redirect' => 'Registration cancelled. Redirecting …', +'Forum rules' => 'Forum rules', +'Rules legend' => 'You must agree to the following in order to register', +'Agree' => 'Agree', +'Cancel' => 'Cancel', +'Register' => 'Register', + +// Form validation stuff (some of these are also used in post.php) +'Username censor' => 'The username you entered contains one or more censored words. Please choose a different username.', +'Username dupe 1' => 'Someone is already registered with the username', +'Username dupe 2' => 'The username you entered is too similar. The username must differ from that by at least one alphanumerical character (a-z or 0-9). Please choose a different username.', +'E-mail not match' => 'E-mail addresses do not match. Please go back and correct.', + +// Registration e-mail stuff +'Reg e-mail' => 'Thank you for registering. Your password has been sent to the specified address. If it doesn\'t arrive you can contact the forum administrator at', +'Reg complete' => 'Registration complete. Logging in and redirecting …', + +// Register info +'Desc 1' => 'Registration will grant you access to a number of features and capabilities otherwise unavailable. These functions include the ability to edit and delete posts, design your own signature that accompanies your posts and much more. If you have any questions regarding this forum you should ask an administrator.', +'Desc 2' => 'Below is a form you must fill out in order to register. Once you are registered you should visit your profile and review the different settings you can change. The fields below only make up a small part of all the settings you can alter in your profile.', +'Username legend' => 'Please enter a username between 2 and 25 characters long', +'Pass legend 1' => 'Please enter and confirm your chosen password', +'Pass legend 2' => 'Please read the instructions below', +'Pass info' => 'Passwords can be between 4 and 16 characters long. Passwords are case sensitive.', +'E-mail info' => 'You must enter a valid e-mail address as your randomly generated password will be sent to that address.', +'Confirm e-mail' => 'Confirm e-mail address', + +); diff -r 000000000000 -r f9ffdbd96607 punbb/lang/English/search.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/punbb/lang/English/search.php Wed Jul 11 21:01:48 2007 -0400 @@ -0,0 +1,47 @@ + 'User search', +'No search permission' => 'You do not have permission to use the search feature.', +'Search' => 'Search', +'Search criteria legend' => 'Enter your search criteria', +'Search info' => 'To search by keyword, enter a term or terms to search for. Separate terms with spaces. Use AND, OR and NOT to refine your search. To search by author enter the username of the author whose posts you wish to search for. Use wildcard character * for partial matches.', +'Keyword search' => 'Keyword search', +'Author search' => 'Author search', +'Search in legend' => 'Select where to search', +'Search in info' => 'Choose in which forum you would like to search and if you want to search in topic subjects, message text or both.', +'Forum search' => 'Forum', +'All forums' => 'All forums', +'Search in' => 'Search in', +'Message and subject' => 'Message text and topic subject', +'Message only' => 'Message text only', +'Topic only' => 'Topic subject only', +'Sort by' => 'Sort by', +'Sort order' => 'Sort order', +'Search results legend' => 'Select how to view search results', +'Search results info' => 'You can choose how you wish to sort and show your results.', +'Sort by post time' => 'Post time', +'Sort by author' => 'Author', +'Sort by subject' => 'Subject', +'Sort by forum' => 'Forum', +'Ascending' => 'Ascending', +'Descending' => 'Descending', +'Show as' => 'Show results as', +'Show as topics' => 'Topics', +'Show as posts' => 'Posts', + +// Results +'Search results' => 'Search results', +'No terms' => 'You have to enter at least one keyword and/or an author to search for.', +'No hits' => 'Your search returned no hits.', +'No user posts' => 'There are no posts by this user in this forum.', +'No subscriptions' => 'You are currently not subscribed to any topics.', +'No new posts' => 'There are no topics with new posts since your last visit.', +'No recent posts' => 'No new posts have been made within the last 24 hours.', +'No unanswered' => 'There are no unanswered posts in this forum.', +'Go to post' => 'Go to post' + +); diff -r 000000000000 -r f9ffdbd96607 punbb/lang/English/stopwords.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/punbb/lang/English/stopwords.txt Wed Jul 11 21:01:48 2007 -0400 @@ -0,0 +1,150 @@ +about +after +ago +all +almost +along +also +any +anybody +anywhere +are +arent +around +ask +been +before +being +between +but +came +can +cant +come +could +couldnt +did +didnt +does +doesnt +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 +ill +into +isnt +its +ive +just +know +less +like +make +many +may +more +most +much +must +near +never +none +nothing +now +off +often +once +one +only +other +our +ours +out +over +please +rather +really +said +see +she +should +small +some +something +sometime +somewhere +take +than +thank +thanks +that +thats +the +their +theirs +them +then +there +these +they +thing +think +this +those +though +through +thus +too +true +two +under +until +upon +use +very +want +was +way +well +were +what +when +where +which +who +whom +whose +why +will +with +within +without +would +yes +yet +you +your +yours \ No newline at end of file diff -r 000000000000 -r f9ffdbd96607 punbb/lang/English/topic.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/punbb/lang/English/topic.php Wed Jul 11 21:01:48 2007 -0400 @@ -0,0 +1,27 @@ + 'Post reply', +'Topic closed' => 'Topic closed', +'From' => 'From', // User location +'Note' => 'Note', // Admin note +'Website' => 'Website', +'Guest' => 'Guest', +'Online' => 'Online', +'Offline' => 'Offline', +'Last edit' => 'Last edited by', +'Report' => 'Report', +'Delete' => 'Delete', +'Edit' => 'Edit', +'Quote' => 'Quote', +'Is subscribed' => 'You are currently subscribed to this topic', +'Unsubscribe' => 'Unsubscribe', +'Subscribe' => 'Subscribe to this topic', +'Quick post' => 'Quick post', + +'Link separator' => ' | ', // The text that separates links in posts (website, e-mail, report, edit etc.) +'Mod controls' => 'Moderator controls' + +); diff -r 000000000000 -r f9ffdbd96607 punbb/lang/English/userlist.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/punbb/lang/English/userlist.php Wed Jul 11 21:01:48 2007 -0400 @@ -0,0 +1,12 @@ + 'Find and sort users', +'User search info' => 'Enter a username to search for and/or a user group to filter by. The username field can be left blank. Use the wildcard character * for partial matches. Sort users by name, date registered or number of posts and in ascending/descending order.', +'User group' => 'User group', +'No of posts' => 'No. of posts', +'All users' => 'All' + +); diff -r 000000000000 -r f9ffdbd96607 punbb/lang/index.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/punbb/lang/index.html Wed Jul 11 21:01:48 2007 -0400 @@ -0,0 +1,8 @@ + + +. + + +. + + \ No newline at end of file diff -r 000000000000 -r f9ffdbd96607 punbb/login.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/punbb/login.php Wed Jul 11 21:01:48 2007 -0400 @@ -0,0 +1,226 @@ +escape($form_username).'\'' : 'LOWER(username)=LOWER(\''.$db->escape($form_username).'\')'; + + $result = $db->query('SELECT id, group_id, password, save_pass FROM '.$db->prefix.'users WHERE '.$username_sql) or error('Unable to fetch user info', __FILE__, __LINE__, $db->error()); + list($user_id, $group_id, $db_password_hash, $save_pass) = $db->fetch_row($result); + + $authorized = false; + + if (!empty($db_password_hash)) + { + $sha1_in_db = (strlen($db_password_hash) == 40) ? true : false; + $sha1_available = (function_exists('sha1') || function_exists('mhash')) ? true : false; + + $form_password_hash = pun_hash($form_password); // This could result in either an SHA-1 or an MD5 hash (depends on $sha1_available) + + if ($sha1_in_db && $sha1_available && $db_password_hash == $form_password_hash) + $authorized = true; + else if (!$sha1_in_db && $db_password_hash == md5($form_password)) + { + $authorized = true; + + if ($sha1_available) // There's an MD5 hash in the database, but SHA1 hashing is available, so we update the DB + $db->query('UPDATE '.$db->prefix.'users SET password=\''.$form_password_hash.'\' WHERE id='.$user_id) or error('Unable to update user password', __FILE__, __LINE__, $db->error()); + } + } + + if (!$authorized) + message($lang_login['Wrong user/pass'].' '.$lang_login['Forgotten pass'].''); + + // Update the status if this is the first time the user logged in + if ($group_id == PUN_UNVERIFIED) + $db->query('UPDATE '.$db->prefix.'users SET group_id='.$pun_config['o_default_user_group'].' WHERE id='.$user_id) or error('Unable to update user status', __FILE__, __LINE__, $db->error()); + + // Remove this users guest entry from the online list + $db->query('DELETE FROM '.$db->prefix.'online WHERE ident=\''.$db->escape(get_remote_address()).'\'') or error('Unable to delete from online list', __FILE__, __LINE__, $db->error()); + + $expire = ($save_pass == '1') ? time() + 31536000 : 0; + pun_setcookie($user_id, $form_password_hash, $expire); + + redirect(htmlspecialchars($_POST['redirect_url']), $lang_login['Login redirect']); +} + + +else if ($action == 'out') +{ + if ($pun_user['is_guest'] || !isset($_GET['id']) || $_GET['id'] != $pun_user['id']) + { + header('Location: index.php'); + exit; + } + + // Remove user from "users online" list. + $db->query('DELETE FROM '.$db->prefix.'online WHERE user_id='.$pun_user['id']) or error('Unable to delete from online list', __FILE__, __LINE__, $db->error()); + + // Update last_visit (make sure there's something to update it with) + if (isset($pun_user['logged'])) + $db->query('UPDATE '.$db->prefix.'users SET last_visit='.$pun_user['logged'].' WHERE id='.$pun_user['id']) or error('Unable to update user visit data', __FILE__, __LINE__, $db->error()); + + pun_setcookie(1, random_pass(8), time() + 31536000); + + redirect('index.php', $lang_login['Logout redirect']); +} + + +else if ($action == 'forget' || $action == 'forget_2') +{ + if (!$pun_user['is_guest']) + header('Location: index.php'); + + if (isset($_POST['form_sent'])) + { + require PUN_ROOT.'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=\''.$db->escape($email).'\'') or error('Unable to fetch user info', __FILE__, __LINE__, $db->error()); + + if ($db->num_rows($result)) + { + // Load the "activate password" template + $mail_tpl = trim(file_get_contents(PUN_ROOT.'lang/'.$pun_user['language'].'/mail_templates/activate_password.tpl')); + + // The first row contains the subject + $first_crlf = strpos($mail_tpl, "\n"); + $mail_subject = trim(substr($mail_tpl, 8, $first_crlf-8)); + $mail_message = trim(substr($mail_tpl, $first_crlf)); + + // Do the generic replacements first (they apply to all e-mails sent out here) + $mail_message = str_replace('', $pun_config['o_base_url'].'/', $mail_message); + $mail_message = str_replace('', $pun_config['o_board_title'].' '.$lang_common['Mailer'], $mail_message); + + // Loop through users we found + while ($cur_hit = $db->fetch_assoc($result)) + { + // Generate a new password and a new password activation code + $new_password = random_pass(8); + $new_password_key = random_pass(8); + + $db->query('UPDATE '.$db->prefix.'users SET activate_string=\''.pun_hash($new_password).'\', activate_key=\''.$new_password_key.'\' WHERE id='.$cur_hit['id']) or error('Unable to update activation data', __FILE__, __LINE__, $db->error()); + + // Do the user specific replacements to the template + $cur_mail_message = str_replace('', $cur_hit['username'], $mail_message); + $cur_mail_message = str_replace('', $pun_config['o_base_url'].'/profile.php?id='.$cur_hit['id'].'&action=change_pass&key='.$new_password_key, $cur_mail_message); + $cur_mail_message = str_replace('', $new_password, $cur_mail_message); + + pun_mail($email, $mail_subject, $cur_mail_message); + } + + message($lang_login['Forget mail'].' '.$pun_config['o_admin_email'].'.'); + } + else + message($lang_login['No e-mail match'].' '.htmlspecialchars($email).'.'); + } + + + $page_title = pun_htmlspecialchars($pun_config['o_board_title']).' / '.$lang_login['Request pass']; + $required_fields = array('req_email' => $lang_common['E-mail']); + $focus_element = array('request_pass', 'req_email'); + require PUN_ROOT.'header.php'; + +?> +
    +

    +
    +
    +
    +
    + +
    + + +

    +
    +
    +
    +

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

    +
    +
    +
    +
    + +
    + + + + +

    +

       +

    +
    +
    +
    +

    +
    +
    +
    + +
    +

    +
    +
    +

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

    +
    +
    +
    +
    + +
    + + + + +

    +
    +
    +
    +

    +
    +
    +
    +query('SELECT topic_id FROM '.$db->prefix.'posts WHERE id='.$post_id) or error('Unable to fetch post info', __FILE__, __LINE__, $db->error()); + if (!$db->num_rows($result)) + message($lang_common['Bad request']); + + $topic_id = $db->result($result); + + // Get the subject and forum ID + $result = $db->query('SELECT subject, forum_id FROM '.$db->prefix.'topics WHERE id='.$topic_id) or error('Unable to fetch topic info', __FILE__, __LINE__, $db->error()); + if (!$db->num_rows($result)) + message($lang_common['Bad request']); + + list($subject, $forum_id) = $db->fetch_row($result); + + // Should we use the internal report handling? + if ($pun_config['o_report_method'] == 0 || $pun_config['o_report_method'] == 2) + $db->query('INSERT INTO '.$db->prefix.'reports (post_id, topic_id, forum_id, reported_by, created, message) VALUES('.$post_id.', '.$topic_id.', '.$forum_id.', '.$pun_user['id'].', '.time().', \''.$db->escape($reason).'\')' ) or error('Unable to create report', __FILE__, __LINE__, $db->error()); + + // Should we e-mail the report? + if ($pun_config['o_report_method'] == 1 || $pun_config['o_report_method'] == 2) + { + // We send it to the complete mailing-list in one swoop + if ($pun_config['o_mailing_list'] != '') + { + $mail_subject = 'Report('.$forum_id.') - \''.$subject.'\''; + $mail_message = 'User \''.$pun_user['username'].'\' has reported the following message:'."\n".$pun_config['o_base_url'].'/viewtopic.php?pid='.$post_id.'#p'.$post_id."\n\n".'Reason:'."\n".$reason; + + require PUN_ROOT.'include/email.php'; + + pun_mail($pun_config['o_mailing_list'], $mail_subject, $mail_message); + } + } + + redirect('viewtopic.php?pid='.$post_id.'#p'.$post_id, $lang_misc['Report redirect']); + } + + + $page_title = pun_htmlspecialchars($pun_config['o_board_title']).' / '.$lang_misc['Report post']; + $required_fields = array('req_reason' => $lang_misc['Reason']); + $focus_element = array('report', 'req_reason'); + require PUN_ROOT.'header.php'; + +?> +
    +

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

    +
    +
    +
    +query('SELECT 1 FROM '.$db->prefix.'subscriptions WHERE user_id='.$pun_user['id'].' AND topic_id='.$topic_id) or error('Unable to fetch subscription info', __FILE__, __LINE__, $db->error()); + if ($db->num_rows($result)) + message($lang_misc['Already subscribed']); + + $db->query('INSERT INTO '.$db->prefix.'subscriptions (user_id, topic_id) VALUES('.$pun_user['id'].' ,'.$topic_id.')') or error('Unable to add subscription', __FILE__, __LINE__, $db->error()); + + redirect('viewtopic.php?id='.$topic_id, $lang_misc['Subscribe redirect']); +} + + +else if (isset($_GET['unsubscribe'])) +{ + if ($pun_user['is_guest'] || $pun_config['o_subscriptions'] != '1') + message($lang_common['No permission']); + + $topic_id = intval($_GET['unsubscribe']); + if ($topic_id < 1) + message($lang_common['Bad request']); + + $result = $db->query('SELECT 1 FROM '.$db->prefix.'subscriptions WHERE user_id='.$pun_user['id'].' AND topic_id='.$topic_id) or error('Unable to fetch subscription info', __FILE__, __LINE__, $db->error()); + if (!$db->num_rows($result)) + message($lang_misc['Not subscribed']); + + $db->query('DELETE FROM '.$db->prefix.'subscriptions WHERE user_id='.$pun_user['id'].' AND topic_id='.$topic_id) or error('Unable to remove subscription', __FILE__, __LINE__, $db->error()); + + redirect('viewtopic.php?id='.$topic_id, $lang_misc['Unsubscribe redirect']); +} + + +else + message($lang_common['Bad request']); diff -r 000000000000 -r f9ffdbd96607 punbb/moderate.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/punbb/moderate.php Wed Jul 11 21:01:48 2007 -0400 @@ -0,0 +1,716 @@ + PUN_MOD) + message($lang_common['No permission']); + + // Is get_host an IP address or a post ID? + if (@preg_match('/[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}/', $_GET['get_host'])) + $ip = $_GET['get_host']; + else + { + $get_host = intval($_GET['get_host']); + if ($get_host < 1) + message($lang_common['Bad request']); + + $result = $db->query('SELECT poster_ip FROM '.$db->prefix.'posts WHERE id='.$get_host) or error('Unable to fetch post IP address', __FILE__, __LINE__, $db->error()); + if (!$db->num_rows($result)) + message($lang_common['Bad request']); + + $ip = $db->result($result); + } + + message('The IP address is: '.$ip.'
    The host name is: '.@gethostbyaddr($ip).'

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

    +
    +
    +
    +
    + +
    + +

    +
    +
    +
    +

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

    # 

    +
    +
    +
    +
    +
    +
    +
    +
    +
    +

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

    '."\n"; ?> +
    + 1) echo '

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

    />

    +
    +
    +
    +
    +query('SELECT 1 FROM '.$db->prefix.'topics WHERE id IN('.implode(',',$topics).') AND forum_id='.$fid) or error('Unable to check topics', __FILE__, __LINE__, $db->error()); + + if ($db->num_rows($result) != count($topics)) + message($lang_common['Bad request']); + + // Delete any redirect topics if there are any (only if we moved/copied the topic back to where it where it was once moved from) + $db->query('DELETE FROM '.$db->prefix.'topics WHERE forum_id='.$move_to_forum.' AND moved_to IN('.implode(',',$topics).')') or error('Unable to delete redirect topics', __FILE__, __LINE__, $db->error()); + + // Move the topic(s) + $db->query('UPDATE '.$db->prefix.'topics SET forum_id='.$move_to_forum.' WHERE id IN('.implode(',',$topics).')') or error('Unable to move topics', __FILE__, __LINE__, $db->error()); + + // Should we create redirect topics? + if (isset($_POST['with_redirect'])) + { + while (list(, $cur_topic) = @each($topics)) + { + // Fetch info for the redirect topic + $result = $db->query('SELECT poster, subject, posted, last_post FROM '.$db->prefix.'topics WHERE id='.$cur_topic) or error('Unable to fetch topic info', __FILE__, __LINE__, $db->error()); + $moved_to = $db->fetch_assoc($result); + + // Create the redirect topic + $db->query('INSERT INTO '.$db->prefix.'topics (poster, subject, posted, last_post, moved_to, forum_id) VALUES(\''.$db->escape($moved_to['poster']).'\', \''.$db->escape($moved_to['subject']).'\', '.$moved_to['posted'].', '.$moved_to['last_post'].', '.$cur_topic.', '.$fid.')') or error('Unable to create redirect topic', __FILE__, __LINE__, $db->error()); + } + } + + update_forum($fid); // Update the forum FROM which the topic was moved + update_forum($move_to_forum); // Update the forum TO which the topic was moved + + $redirect_msg = (count($topics) > 1) ? $lang_misc['Move topics redirect'] : $lang_misc['Move topic redirect']; + redirect('viewforum.php?id='.$move_to_forum, $redirect_msg); + } + + if (isset($_POST['move_topics'])) + { + $topics = isset($_POST['topics']) ? $_POST['topics'] : array(); + if (empty($topics)) + message($lang_misc['No topics selected']); + + $topics = implode(',', array_keys($topics)); + $action = 'multi'; + } + else + { + $topics = intval($_GET['move_topics']); + if ($topics < 1) + message($lang_common['Bad request']); + + $action = 'single'; + } + + $page_title = pun_htmlspecialchars($pun_config['o_board_title']).' / Moderate'; + require PUN_ROOT.'header.php'; + +?> +
    +

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

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

    +
    +
    + +
    +
    + +
    +

    +
    +
    +
    +

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

    +
    +
    + + + + + + + + + + + +query('SELECT id, poster, subject, posted, last_post, last_post_id, last_poster, num_views, num_replies, closed, sticky, moved_to FROM '.$db->prefix.'topics WHERE forum_id='.$fid.' ORDER BY sticky DESC, last_post DESC LIMIT '.$start_from.', '.$pun_user['disp_topics']) or error('Unable to fetch topic list for forum', __FILE__, __LINE__, $db->error()); + +// If there are topics in this forum. +if ($db->num_rows($result)) +{ + $button_status = ''; + + while ($cur_topic = $db->fetch_assoc($result)) + { + + $icon_text = $lang_common['Normal icon']; + $item_status = ''; + $icon_type = 'icon'; + + if ($cur_topic['moved_to'] == null) + { + $last_post = ''.format_time($cur_topic['last_post']).' '.$lang_common['by'].' '.pun_htmlspecialchars($cur_topic['last_poster']); + $ghost_topic = false; + } + else + { + $last_post = ' '; + $ghost_topic = true; + } + + if ($pun_config['o_censoring'] == '1') + $cur_topic['subject'] = censor_words($cur_topic['subject']); + + if ($cur_topic['moved_to'] != 0) + $subject = $lang_forum['Moved'].': '.pun_htmlspecialchars($cur_topic['subject']).''.$lang_common['by'].' '.pun_htmlspecialchars($cur_topic['poster']).''; + else if ($cur_topic['closed'] == '0') + $subject = ''.pun_htmlspecialchars($cur_topic['subject']).''.$lang_common['by'].' '.pun_htmlspecialchars($cur_topic['poster']).''; + else + { + $subject = ''.pun_htmlspecialchars($cur_topic['subject']).''.$lang_common['by'].' '.pun_htmlspecialchars($cur_topic['poster']).''; + $icon_text = $lang_common['Closed icon']; + $item_status = 'iclosed'; + } + + if ($cur_topic['last_post'] > $pun_user['last_visit'] && !$ghost_topic) + { + $icon_text .= ' '.$lang_common['New icon']; + $item_status .= ' inew'; + $icon_type = 'icon inew'; + $subject = ''.$subject.''; + $subject_new_posts = ''.$lang_common['New posts'].' ]'; + } + else + $subject_new_posts = null; + + // We won't display "the dot", but we add the spaces anyway + if ($pun_config['o_show_dot'] == '1') + $subject = '  '.$subject; + + if ($cur_topic['sticky'] == '1') + { + $subject = ''.$lang_forum['Sticky'].': '.$subject; + $item_status .= ' isticky'; + $icon_text .= ' '.$lang_forum['Sticky']; + } + + $num_pages_topic = ceil(($cur_topic['num_replies'] + 1) / $pun_user['disp_posts']); + + if ($num_pages_topic > 1) + $subject_multipage = '[ '.paginate($num_pages_topic, -1, 'viewtopic.php?id='.$cur_topic['id']).' ]'; + else + $subject_multipage = null; + + // Should we show the "New posts" and/or the multipage links? + if (!empty($subject_new_posts) || !empty($subject_multipage)) + { + $subject .= '  '.(!empty($subject_new_posts) ? $subject_new_posts : ''); + $subject .= !empty($subject_multipage) ? ' '.$subject_multipage : ''; + } + +?> + > + + + + + + +'."\n"; +} + +?> + +
    +
    +
    + +
    +
    '.$lang_forum['Empty forum'].'
    +
    +
    +
    + +
    +
    + +

    />   />   />   />

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

    Example plugin

    +
    +
    +

    You said "". Great stuff.

    +

    Go back

    +
    +
    +
    + +
    +

    Example plugin

    +
    +
    +

    This plugin doesn't do anything useful. Hence the name "Example".

    +

    This would be a good spot to talk a little about your plugin. Describe what it does and how it should be used. Be brief, but informative.

    +
    +
    + +

    An example form

    +
    +
    +
    +
    + Enter a piece of text and hit "Show text"! +
    + + + + + +
    Text to show
    + + The text you want to display. +
    +
    +
    +
    +
    +
    +
    + + +. + + +. + + \ No newline at end of file diff -r 000000000000 -r f9ffdbd96607 punbb/post.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/punbb/post.php Wed Jul 11 21:01:48 2007 -0400 @@ -0,0 +1,596 @@ + 0 && $fid > 0) + message($lang_common['Bad request']); + +// Fetch some info about the topic and/or the forum +if ($tid) + $result = $db->query('SELECT f.id, f.forum_name, f.moderators, f.redirect_url, fp.post_replies, fp.post_topics, t.subject, t.closed FROM '.$db->prefix.'topics AS t INNER JOIN '.$db->prefix.'forums AS f ON f.id=t.forum_id LEFT JOIN '.$db->prefix.'forum_perms AS fp ON (fp.forum_id=f.id AND fp.group_id='.$pun_user['g_id'].') WHERE (fp.read_forum IS NULL OR fp.read_forum=1) AND t.id='.$tid) or error('Unable to fetch forum info', __FILE__, __LINE__, $db->error()); +else + $result = $db->query('SELECT f.id, f.forum_name, f.moderators, f.redirect_url, fp.post_replies, fp.post_topics FROM '.$db->prefix.'forums AS f LEFT JOIN '.$db->prefix.'forum_perms AS fp ON (fp.forum_id=f.id AND fp.group_id='.$pun_user['g_id'].') WHERE (fp.read_forum IS NULL OR fp.read_forum=1) AND f.id='.$fid) or error('Unable to fetch forum info', __FILE__, __LINE__, $db->error()); + +if (!$db->num_rows($result)) + message($lang_common['Bad request']); + +$cur_posting = $db->fetch_assoc($result); + +// Is someone trying to post into a redirect forum? +if ($cur_posting['redirect_url'] != '') + message($lang_common['Bad request']); + +// Sort out who the moderators are and if we are currently a moderator (or an admin) +$mods_array = ($cur_posting['moderators'] != '') ? unserialize($cur_posting['moderators']) : array(); +$is_admmod = ($pun_user['g_id'] == PUN_ADMIN || ($pun_user['g_id'] == PUN_MOD && array_key_exists($pun_user['username'], $mods_array))) ? true : false; + +// Do we have permission to post? +if ((($tid && (($cur_posting['post_replies'] == '' && $pun_user['g_post_replies'] == '0') || $cur_posting['post_replies'] == '0')) || + ($fid && (($cur_posting['post_topics'] == '' && $pun_user['g_post_topics'] == '0') || $cur_posting['post_topics'] == '0')) || + (isset($cur_posting['closed']) && $cur_posting['closed'] == '1')) && + !$is_admmod) + message($lang_common['No permission']); + +// Load the post.php language file +require PUN_ROOT.'lang/'.$pun_user['language'].'/post.php'; + +// Start with a clean slate +$errors = array(); + + +// Did someone just hit "Submit" or "Preview"? +if (isset($_POST['form_sent'])) +{ + // Make sure form_user is correct + if (($pun_user['is_guest'] && $_POST['form_user'] != 'Guest') || (!$pun_user['is_guest'] && $_POST['form_user'] != $pun_user['username'])) + message($lang_common['Bad request']); + + // Flood protection + if (!$pun_user['is_guest'] && !isset($_POST['preview']) && $pun_user['last_post'] != '' && (time() - $pun_user['last_post']) < $pun_user['g_post_flood']) + $errors[] = $lang_post['Flood start'].' '.$pun_user['g_post_flood'].' '.$lang_post['flood end']; + + // If it's a new topic + if ($fid) + { + $subject = pun_trim($_POST['req_subject']); + + if ($subject == '') + $errors[] = $lang_post['No subject']; + else if (pun_strlen($subject) > 70) + $errors[] = $lang_post['Too long subject']; + else if ($pun_config['p_subject_all_caps'] == '0' && strtoupper($subject) == $subject && $pun_user['g_id'] > PUN_MOD) + $subject = ucwords(strtolower($subject)); + } + + // If the user is logged in we get the username and e-mail from $pun_user + if (!$pun_user['is_guest']) + { + $username = $pun_user['username']; + $email = $pun_user['email']; + } + // Otherwise it should be in $_POST + else + { + $username = trim($_POST['req_username']); + $email = strtolower(trim(($pun_config['p_force_guest_email'] == '1') ? $_POST['req_email'] : $_POST['email'])); + + // Load the register.php/profile.php language files + require PUN_ROOT.'lang/'.$pun_user['language'].'/prof_reg.php'; + require PUN_ROOT.'lang/'.$pun_user['language'].'/register.php'; + + // It's a guest, so we have to validate the username + if (strlen($username) < 2) + $errors[] = $lang_prof_reg['Username too short']; + else if (!strcasecmp($username, 'Guest') || !strcasecmp($username, $lang_common['Guest'])) + $errors[] = $lang_prof_reg['Username guest']; + else if (preg_match('/[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}/', $username)) + $errors[] = $lang_prof_reg['Username IP']; + + if ((strpos($username, '[') !== false || strpos($username, ']') !== false) && strpos($username, '\'') !== false && strpos($username, '"') !== false) + $errors[] = $lang_prof_reg['Username reserved chars']; + if (preg_match('#\[b\]|\[/b\]|\[u\]|\[/u\]|\[i\]|\[/i\]|\[color|\[/color\]|\[quote\]|\[quote=|\[/quote\]|\[code\]|\[/code\]|\[img\]|\[/img\]|\[url|\[/url\]|\[email|\[/email\]#i', $username)) + $errors[] = $lang_prof_reg['Username BBCode']; + + // Check username for any censored words + $temp = censor_words($username); + if ($temp != $username) + $errors[] = $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=\''.$db->escape($username).'\' OR username=\''.$db->escape(preg_replace('/[^\w]/', '', $username)).'\') AND id>1') or error('Unable to fetch user info', __FILE__, __LINE__, $db->error()); + if ($db->num_rows($result)) + { + $busy = $db->result($result); + $errors[] = $lang_register['Username dupe 1'].' '.pun_htmlspecialchars($busy).'. '.$lang_register['Username dupe 2']; + } + + if ($pun_config['p_force_guest_email'] == '1' || $email != '') + { + require PUN_ROOT.'include/email.php'; + if (!is_valid_email($email)) + $errors[] = $lang_common['Invalid e-mail']; + } + } + + // Clean up message from POST + $message = pun_linebreaks(pun_trim($_POST['req_message'])); + + if ($message == '') + $errors[] = $lang_post['No message']; + else if (strlen($message) > 65535) + $errors[] = $lang_post['Too long message']; + else if ($pun_config['p_message_all_caps'] == '0' && strtoupper($message) == $message && $pun_user['g_id'] > PUN_MOD) + $message = ucwords(strtolower($message)); + + // Validate BBCode syntax + if ($pun_config['p_message_bbcode'] == '1' && strpos($message, '[') !== false && strpos($message, ']') !== false) + { + require PUN_ROOT.'include/parser.php'; + $message = preparse_bbcode($message, $errors); + } + + + require PUN_ROOT.'include/search_idx.php'; + + $hide_smilies = isset($_POST['hide_smilies']) ? 1 : 0; + $subscribe = isset($_POST['subscribe']) ? 1 : 0; + + $now = time(); + + // Did everything go according to plan? + if (empty($errors) && !isset($_POST['preview'])) + { + // If it's a reply + if ($tid) + { + if (!$pun_user['is_guest']) + { + // Insert the new post + $db->query('INSERT INTO '.$db->prefix.'posts (poster, poster_id, poster_ip, message, hide_smilies, posted, topic_id) VALUES(\''.$db->escape($username).'\', '.$pun_user['id'].', \''.get_remote_address().'\', \''.$db->escape($message).'\', \''.$hide_smilies.'\', '.$now.', '.$tid.')') or error('Unable to create post', __FILE__, __LINE__, $db->error()); + $new_pid = $db->insert_id(); + + // To subscribe or not to subscribe, that ... + if ($pun_config['o_subscriptions'] == '1' && $subscribe) + { + $result = $db->query('SELECT 1 FROM '.$db->prefix.'subscriptions WHERE user_id='.$pun_user['id'].' AND topic_id='.$tid) or error('Unable to fetch subscription info', __FILE__, __LINE__, $db->error()); + if (!$db->num_rows($result)) + $db->query('INSERT INTO '.$db->prefix.'subscriptions (user_id, topic_id) VALUES('.$pun_user['id'].' ,'.$tid.')') or error('Unable to add subscription', __FILE__, __LINE__, $db->error()); + } + } + else + { + // It's a guest. Insert the new post + $email_sql = ($pun_config['p_force_guest_email'] == '1' || $email != '') ? '\''.$email.'\'' : 'NULL'; + $db->query('INSERT INTO '.$db->prefix.'posts (poster, poster_ip, poster_email, message, hide_smilies, posted, topic_id) VALUES(\''.$db->escape($username).'\', \''.get_remote_address().'\', '.$email_sql.', \''.$db->escape($message).'\', \''.$hide_smilies.'\', '.$now.', '.$tid.')') or error('Unable to create post', __FILE__, __LINE__, $db->error()); + $new_pid = $db->insert_id(); + } + + // Count number of replies in the topic + $result = $db->query('SELECT COUNT(id) FROM '.$db->prefix.'posts WHERE topic_id='.$tid) or error('Unable to fetch post count for topic', __FILE__, __LINE__, $db->error()); + $num_replies = $db->result($result, 0) - 1; + + // Update topic + $db->query('UPDATE '.$db->prefix.'topics SET num_replies='.$num_replies.', last_post='.$now.', last_post_id='.$new_pid.', last_poster=\''.$db->escape($username).'\' WHERE id='.$tid) or error('Unable to update topic', __FILE__, __LINE__, $db->error()); + + update_search_index('post', $new_pid, $message); + + update_forum($cur_posting['id']); + + // Should we send out notifications? + if ($pun_config['o_subscriptions'] == '1') + { + // Get the post time for the previous post in this topic + $result = $db->query('SELECT posted FROM '.$db->prefix.'posts WHERE topic_id='.$tid.' ORDER BY id DESC LIMIT 1, 1') or error('Unable to fetch post info', __FILE__, __LINE__, $db->error()); + $previous_post_time = $db->result($result); + + // Get any subscribed users that should be notified (banned users are excluded) + $result = $db->query('SELECT u.id, u.email, u.notify_with_post, u.language FROM '.$db->prefix.'users AS u INNER JOIN '.$db->prefix.'subscriptions AS s ON u.id=s.user_id LEFT JOIN '.$db->prefix.'forum_perms AS fp ON (fp.forum_id='.$cur_posting['id'].' AND fp.group_id=u.group_id) LEFT JOIN '.$db->prefix.'online AS o ON u.id=o.user_id LEFT JOIN '.$db->prefix.'bans AS b ON u.username=b.username WHERE b.username IS NULL AND COALESCE(o.logged, u.last_visit)>'.$previous_post_time.' AND (fp.read_forum IS NULL OR fp.read_forum=1) AND s.topic_id='.$tid.' AND u.id!='.intval($pun_user['id'])) or error('Unable to fetch subscription info', __FILE__, __LINE__, $db->error()); + if ($db->num_rows($result)) + { + require_once PUN_ROOT.'include/email.php'; + + $notification_emails = array(); + + // Loop through subscribed users and send e-mails + while ($cur_subscriber = $db->fetch_assoc($result)) + { + // Is the subscription e-mail for $cur_subscriber['language'] cached or not? + if (!isset($notification_emails[$cur_subscriber['language']])) + { + if (file_exists(PUN_ROOT.'lang/'.$cur_subscriber['language'].'/mail_templates/new_reply.tpl')) + { + // Load the "new reply" template + $mail_tpl = trim(file_get_contents(PUN_ROOT.'lang/'.$cur_subscriber['language'].'/mail_templates/new_reply.tpl')); + + // Load the "new reply full" template (with post included) + $mail_tpl_full = trim(file_get_contents(PUN_ROOT.'lang/'.$cur_subscriber['language'].'/mail_templates/new_reply_full.tpl')); + + // The first row contains the subject (it also starts with "Subject:") + $first_crlf = strpos($mail_tpl, "\n"); + $mail_subject = trim(substr($mail_tpl, 8, $first_crlf-8)); + $mail_message = trim(substr($mail_tpl, $first_crlf)); + + $first_crlf = strpos($mail_tpl_full, "\n"); + $mail_subject_full = trim(substr($mail_tpl_full, 8, $first_crlf-8)); + $mail_message_full = trim(substr($mail_tpl_full, $first_crlf)); + + $mail_subject = str_replace('', '\''.$cur_posting['subject'].'\'', $mail_subject); + $mail_message = str_replace('', '\''.$cur_posting['subject'].'\'', $mail_message); + $mail_message = str_replace('', $username, $mail_message); + $mail_message = str_replace('', $pun_config['o_base_url'].'/viewtopic.php?pid='.$new_pid.'#p'.$new_pid, $mail_message); + $mail_message = str_replace('', $pun_config['o_base_url'].'/misc.php?unsubscribe='.$tid, $mail_message); + $mail_message = str_replace('', $pun_config['o_board_title'].' '.$lang_common['Mailer'], $mail_message); + + $mail_subject_full = str_replace('', '\''.$cur_posting['subject'].'\'', $mail_subject_full); + $mail_message_full = str_replace('', '\''.$cur_posting['subject'].'\'', $mail_message_full); + $mail_message_full = str_replace('', $username, $mail_message_full); + $mail_message_full = str_replace('', $message, $mail_message_full); + $mail_message_full = str_replace('', $pun_config['o_base_url'].'/viewtopic.php?pid='.$new_pid.'#p'.$new_pid, $mail_message_full); + $mail_message_full = str_replace('', $pun_config['o_base_url'].'/misc.php?unsubscribe='.$tid, $mail_message_full); + $mail_message_full = str_replace('', $pun_config['o_board_title'].' '.$lang_common['Mailer'], $mail_message_full); + + $notification_emails[$cur_subscriber['language']][0] = $mail_subject; + $notification_emails[$cur_subscriber['language']][1] = $mail_message; + $notification_emails[$cur_subscriber['language']][2] = $mail_subject_full; + $notification_emails[$cur_subscriber['language']][3] = $mail_message_full; + + $mail_subject = $mail_message = $mail_subject_full = $mail_message_full = null; + } + } + + // We have to double check here because the templates could be missing + if (isset($notification_emails[$cur_subscriber['language']])) + { + if ($cur_subscriber['notify_with_post'] == '0') + pun_mail($cur_subscriber['email'], $notification_emails[$cur_subscriber['language']][0], $notification_emails[$cur_subscriber['language']][1]); + else + pun_mail($cur_subscriber['email'], $notification_emails[$cur_subscriber['language']][2], $notification_emails[$cur_subscriber['language']][3]); + } + } + } + } + } + // If it's a new topic + else if ($fid) + { + // Create the topic + $db->query('INSERT INTO '.$db->prefix.'topics (poster, subject, posted, last_post, last_poster, forum_id) VALUES(\''.$db->escape($username).'\', \''.$db->escape($subject).'\', '.$now.', '.$now.', \''.$db->escape($username).'\', '.$fid.')') or error('Unable to create topic', __FILE__, __LINE__, $db->error()); + $new_tid = $db->insert_id(); + + if (!$pun_user['is_guest']) + { + // To subscribe or not to subscribe, that ... + if ($pun_config['o_subscriptions'] == '1' && (isset($_POST['subscribe']) && $_POST['subscribe'] == '1')) + $db->query('INSERT INTO '.$db->prefix.'subscriptions (user_id, topic_id) VALUES('.$pun_user['id'].' ,'.$new_tid.')') or error('Unable to add subscription', __FILE__, __LINE__, $db->error()); + + // Create the post ("topic post") + $db->query('INSERT INTO '.$db->prefix.'posts (poster, poster_id, poster_ip, message, hide_smilies, posted, topic_id) VALUES(\''.$db->escape($username).'\', '.$pun_user['id'].', \''.get_remote_address().'\', \''.$db->escape($message).'\', \''.$hide_smilies.'\', '.$now.', '.$new_tid.')') or error('Unable to create post', __FILE__, __LINE__, $db->error()); + } + else + { + // Create the post ("topic post") + $email_sql = ($pun_config['p_force_guest_email'] == '1' || $email != '') ? '\''.$email.'\'' : 'NULL'; + $db->query('INSERT INTO '.$db->prefix.'posts (poster, poster_ip, poster_email, message, hide_smilies, posted, topic_id) VALUES(\''.$db->escape($username).'\', \''.get_remote_address().'\', '.$email_sql.', \''.$db->escape($message).'\', \''.$hide_smilies.'\', '.$now.', '.$new_tid.')') or error('Unable to create post', __FILE__, __LINE__, $db->error()); + } + $new_pid = $db->insert_id(); + + // Update the topic with last_post_id + $db->query('UPDATE '.$db->prefix.'topics SET last_post_id='.$new_pid.' WHERE id='.$new_tid) or error('Unable to update topic', __FILE__, __LINE__, $db->error()); + + update_search_index('post', $new_pid, $message, $subject); + + update_forum($fid); + } + + // If the posting user is logged in, increment his/her post count + if (!$pun_user['is_guest']) + { + $low_prio = ($db_type == 'mysql') ? 'LOW_PRIORITY ' : ''; + $db->query('UPDATE '.$low_prio.$db->prefix.'users SET num_posts=num_posts+1, last_post='.$now.' WHERE id='.$pun_user['id']) or error('Unable to update user', __FILE__, __LINE__, $db->error()); + } + + redirect('viewtopic.php?pid='.$new_pid.'#p'.$new_pid, $lang_post['Post redirect']); + } +} + + +// If a topic id was specified in the url (it's a reply). +if ($tid) +{ + $action = $lang_post['Post a reply']; + $form = '
    '; + + // If a quote-id was specified in the url. + if (isset($_GET['qid'])) + { + $qid = intval($_GET['qid']); + if ($qid < 1) + message($lang_common['Bad request']); + + $result = $db->query('SELECT poster, message FROM '.$db->prefix.'posts WHERE id='.$qid.' AND topic_id='.$tid) or error('Unable to fetch quote info', __FILE__, __LINE__, $db->error()); + if (!$db->num_rows($result)) + message($lang_common['Bad request']); + + list($q_poster, $q_message) = $db->fetch_row($result); + + $q_message = str_replace('[img]', '[url]', $q_message); + $q_message = str_replace('[/img]', '[/url]', $q_message); + $q_message = pun_htmlspecialchars($q_message); + + if ($pun_config['p_message_bbcode'] == '1') + { + // If username contains a square bracket, we add "" or '' around it (so we know when it starts and ends) + if (strpos($q_poster, '[') !== false || strpos($q_poster, ']') !== false) + { + if (strpos($q_poster, '\'') !== false) + $q_poster = '"'.$q_poster.'"'; + else + $q_poster = '\''.$q_poster.'\''; + } + else + { + // Get the characters at the start and end of $q_poster + $ends = substr($q_poster, 0, 1).substr($q_poster, -1, 1); + + // Deal with quoting "Username" or 'Username' (becomes '"Username"' or "'Username'") + if ($ends == '\'\'') + $q_poster = '"'.$q_poster.'"'; + else if ($ends == '""') + $q_poster = '\''.$q_poster.'\''; + } + + $quote = '[quote='.$q_poster.']'.$q_message.'[/quote]'."\n"; + } + else + $quote = '> '.$q_poster.' '.$lang_common['wrote'].':'."\n\n".'> '.$q_message."\n"; + } + + $forum_name = ''.pun_htmlspecialchars($cur_posting['forum_name']).''; +} +// If a forum_id was specified in the url (new topic). +else if ($fid) +{ + $action = $lang_post['Post new topic']; + $form = ''; + + $forum_name = pun_htmlspecialchars($cur_posting['forum_name']); +} +else + message($lang_common['Bad request']); + + +$page_title = pun_htmlspecialchars($pun_config['o_board_title']).' / '.$action; +$required_fields = array('req_email' => $lang_common['E-mail'], 'req_subject' => $lang_common['Subject'], 'req_message' => $lang_common['Message']); +$focus_element = array('post'); + +if (!$pun_user['is_guest']) + $focus_element[] = ($fid) ? 'req_subject' : 'req_message'; +else +{ + $required_fields['req_username'] = $lang_post['Guest name']; + $focus_element[] = 'req_username'; +} + +require PUN_ROOT.'header.php'; + +?> +
    +
    +
    •  » 
    •  » '.pun_htmlspecialchars($cur_posting['subject']) ?>
    +
    +
    + + +
    +

    +
    +
    +

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

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

    +
    + +
    +
    + +
    + + +'.$lang_common['E-mail'].'' : $lang_common['E-mail']; + $email_form_name = ($pun_config['p_force_guest_email'] == '1') ? 'req_email' : 'email'; + +?> + +
    + + + + +
    +
    +'.$lang_post['Hide smilies']; + + if ($pun_config['o_subscriptions'] == '1') + $checkboxes[] = '
    +
    +
    + +
    +
    + '."\n\t\t\t\t", $checkboxes).'
    '."\n" ?> +
    +
    +
    + +
    +

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

    +fetch_assoc($result)) + { + // Switch the background color for every message. + $bg_switch = ($bg_switch) ? $bg_switch = false : $bg_switch = true; + $vtbg = ($bg_switch) ? ' roweven' : ' rowodd'; + $post_count++; + + $cur_post['message'] = parse_message($cur_post['message'], $cur_post['hide_smilies']); + +?> +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    + +
    +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_hash, $new_password_key) = $db->fetch_row($result); + + if ($key == '' || $key != $new_password_key) + message($lang_profile['Pass key bad'].' '.$pun_config['o_admin_email'].'.'); + else + { + $db->query('UPDATE '.$db->prefix.'users SET password=\''.$new_password_hash.'\', activate_string=NULL, activate_key=NULL WHERE id='.$id) or error('Unable to update password', __FILE__, __LINE__, $db->error()); + + message($lang_profile['Pass updated'], true); + } + } + + // Make sure we are allowed to change this users password + if ($pun_user['id'] != $id) + { + if ($pun_user['g_id'] > PUN_MOD) // A regular user trying to change another users password? + message($lang_common['No permission']); + else if ($pun_user['g_id'] == PUN_MOD) // A moderator trying to change a users password? + { + $result = $db->query('SELECT group_id 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']); + + if ($pun_config['p_mod_edit_users'] == '0' || $pun_config['p_mod_change_passwords'] == '0' || $db->result($result) < PUN_GUEST) + message($lang_common['No permission']); + } + } + + if (isset($_POST['form_sent'])) + { + $old_password = isset($_POST['req_old_password']) ? trim($_POST['req_old_password']) : ''; + $new_password1 = trim($_POST['req_new_password1']); + $new_password2 = trim($_POST['req_new_password2']); + + if ($new_password1 != $new_password2) + message($lang_prof_reg['Pass not match']); + if (strlen($new_password1) < 4) + message($lang_prof_reg['Pass too short']); + + $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($db_password_hash, $save_pass) = $db->fetch_row($result); + + $authorized = false; + + if (!empty($db_password_hash)) + { + $sha1_in_db = (strlen($db_password_hash) == 40) ? true : false; + $sha1_available = (function_exists('sha1') || function_exists('mhash')) ? true : false; + + $old_password_hash = pun_hash($old_password); // This could result in either an SHA-1 or an MD5 hash + + if (($sha1_in_db && $sha1_available && $db_password_hash == $old_password_hash) || + (!$sha1_in_db && $db_password_hash == md5($old_password)) || + $pun_user['g_id'] < PUN_GUEST) + $authorized = true; + } + + if (!$authorized) + message($lang_profile['Wrong pass']); + + $new_password_hash = pun_hash($new_password1); + + $db->query('UPDATE '.$db->prefix.'users SET password=\''.$new_password_hash.'\' WHERE id='.$id) or error('Unable to update password', __FILE__, __LINE__, $db->error()); + + if ($pun_user['id'] == $id) + { + $expire = ($save_pass == '1') ? time() + 31536000 : 0; + pun_setcookie($pun_user['id'], $new_password_hash, $expire); + } + + redirect('profile.php?section=essentials&id='.$id, $lang_profile['Pass updated redirect']); + } + + $page_title = pun_htmlspecialchars($pun_config['o_board_title']).' / '.$lang_common['Profile']; + $required_fields = array('req_old_password' => $lang_profile['Old pass'], 'req_new_password1' => $lang_profile['New pass'], 'req_new_password2' => $lang_profile['Confirm new pass']); + $focus_element = array('change_pass', (($pun_user['g_id'] > PUN_MOD) ? 'req_old_password' : 'req_new_password1')); + require PUN_ROOT.'header.php'; + +?> +
    +

    +
    +
    +
    + +
    + +
    + PUN_MOD): ?> + + +
    +
    +
    +
    +

    +
    +
    +
    + PUN_MOD) // A regular user trying to change another users e-mail? + message($lang_common['No permission']); + else if ($pun_user['g_id'] == PUN_MOD) // A moderator trying to change a users e-mail? + { + $result = $db->query('SELECT group_id 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']); + + if ($pun_config['p_mod_edit_users'] == '0' || $db->result($result) < PUN_GUEST) + message($lang_common['No permission']); + } + } + + if (isset($_GET['key'])) + { + $key = $_GET['key']; + + $result = $db->query('SELECT activate_string, activate_key FROM '.$db->prefix.'users WHERE id='.$id) or error('Unable to fetch activation data', __FILE__, __LINE__, $db->error()); + list($new_email, $new_email_key) = $db->fetch_row($result); + + if ($key == '' || $key != $new_email_key) + message($lang_profile['E-mail key bad'].' '.$pun_config['o_admin_email'].'.'); + else + { + $db->query('UPDATE '.$db->prefix.'users SET email=activate_string, activate_string=NULL, activate_key=NULL WHERE id='.$id) or error('Unable to update e-mail address', __FILE__, __LINE__, $db->error()); + + message($lang_profile['E-mail updated'], true); + } + } + else if (isset($_POST['form_sent'])) + { + if (pun_hash($_POST['req_password']) !== $pun_user['password']) + message($lang_profile['Wrong pass']); + + require PUN_ROOT.'include/email.php'; + + // Validate the email-address + $new_email = strtolower(trim($_POST['req_new_email'])); + if (!is_valid_email($new_email)) + message($lang_common['Invalid e-mail']); + + // Check it it's a banned e-mail address + if (is_banned_email($new_email)) + { + if ($pun_config['p_allow_banned_email'] == '0') + message($lang_prof_reg['Banned e-mail']); + else if ($pun_config['o_mailing_list'] != '') + { + $mail_subject = 'Alert - Banned e-mail detected'; + $mail_message = 'User \''.$pun_user['username'].'\' changed to banned e-mail address: '.$new_email."\n\n".'User profile: '.$pun_config['o_base_url'].'/profile.php?id='.$id."\n\n".'-- '."\n".'Forum Mailer'."\n".'(Do not reply to this message)'; + + pun_mail($pun_config['o_mailing_list'], $mail_subject, $mail_message); + } + } + + // Check if someone else already has registered with that e-mail address + $result = $db->query('SELECT id, username FROM '.$db->prefix.'users WHERE email=\''.$db->escape($new_email).'\'') or error('Unable to fetch user info', __FILE__, __LINE__, $db->error()); + if ($db->num_rows($result)) + { + if ($pun_config['p_allow_dupe_email'] == '0') + message($lang_prof_reg['Dupe e-mail']); + else if ($pun_config['o_mailing_list'] != '') + { + while ($cur_dupe = $db->fetch_assoc($result)) + $dupe_list[] = $cur_dupe['username']; + + $mail_subject = 'Alert - Duplicate e-mail detected'; + $mail_message = 'User \''.$pun_user['username'].'\' changed to an e-mail address that also belongs to: '.implode(', ', $dupe_list)."\n\n".'User profile: '.$pun_config['o_base_url'].'/profile.php?id='.$id."\n\n".'-- '."\n".'Forum Mailer'."\n".'(Do not reply to this message)'; + + pun_mail($pun_config['o_mailing_list'], $mail_subject, $mail_message); + } + } + + + $new_email_key = random_pass(8); + + $db->query('UPDATE '.$db->prefix.'users SET activate_string=\''.$db->escape($new_email).'\', activate_key=\''.$new_email_key.'\' WHERE id='.$id) or error('Unable to update activation data', __FILE__, __LINE__, $db->error()); + + // Load the "activate e-mail" template + $mail_tpl = trim(file_get_contents(PUN_ROOT.'lang/'.$pun_user['language'].'/mail_templates/activate_email.tpl')); + + // The first row contains the subject + $first_crlf = strpos($mail_tpl, "\n"); + $mail_subject = trim(substr($mail_tpl, 8, $first_crlf-8)); + $mail_message = trim(substr($mail_tpl, $first_crlf)); + + $mail_message = str_replace('', $pun_user['username'], $mail_message); + $mail_message = str_replace('', $pun_config['o_base_url'], $mail_message); + $mail_message = str_replace('', $pun_config['o_base_url'].'/profile.php?action=change_email&id='.$id.'&key='.$new_email_key, $mail_message); + $mail_message = str_replace('', $pun_config['o_board_title'].' '.$lang_common['Mailer'], $mail_message); + + pun_mail($new_email, $mail_subject, $mail_message); + + message($lang_profile['Activate e-mail sent'].' '.$pun_config['o_admin_email'].'.', true); + } + + $page_title = pun_htmlspecialchars($pun_config['o_board_title']).' / '.$lang_common['Profile']; + $required_fields = array('req_new_email' => $lang_profile['New e-mail'], 'req_password' => $lang_common['Password']); + $focus_element = array('change_email', 'req_new_email'); + require PUN_ROOT.'header.php'; + +?> +
    +

    +
    +
    +
    +
    + +
    + + + +

    +
    +
    +
    +

    +
    +
    +
    + PUN_MOD) + message($lang_common['No permission']); + + if (isset($_POST['form_sent'])) + { + if (!isset($_FILES['req_file'])) + message($lang_profile['No file']); + + $uploaded_file = $_FILES['req_file']; + + // Make sure the upload went smooth + if (isset($uploaded_file['error'])) + { + switch ($uploaded_file['error']) + { + case 1: // UPLOAD_ERR_INI_SIZE + case 2: // UPLOAD_ERR_FORM_SIZE + message($lang_profile['Too large ini']); + break; + + case 3: // UPLOAD_ERR_PARTIAL + message($lang_profile['Partial upload']); + break; + + case 4: // UPLOAD_ERR_NO_FILE + message($lang_profile['No file']); + break; + + case 6: // UPLOAD_ERR_NO_TMP_DIR + message($lang_profile['No tmp directory']); + break; + + default: + // No error occured, but was something actually uploaded? + if ($uploaded_file['size'] == 0) + message($lang_profile['No file']); + break; + } + } + + if (is_uploaded_file($uploaded_file['tmp_name'])) + { + $allowed_types = array('image/gif', 'image/jpeg', 'image/pjpeg', 'image/png', 'image/x-png'); + if (!in_array($uploaded_file['type'], $allowed_types)) + message($lang_profile['Bad type']); + + // Make sure the file isn't too big + if ($uploaded_file['size'] > $pun_config['o_avatars_size']) + message($lang_profile['Too large'].' '.$pun_config['o_avatars_size'].' '.$lang_profile['bytes'].'.'); + + // Determine type + $extensions = null; + if ($uploaded_file['type'] == 'image/gif') + $extensions = array('.gif', '.jpg', '.png'); + else if ($uploaded_file['type'] == 'image/jpeg' || $uploaded_file['type'] == 'image/pjpeg') + $extensions = array('.jpg', '.gif', '.png'); + else + $extensions = array('.png', '.gif', '.jpg'); + + // Move the file to the avatar directory. We do this before checking the width/height to circumvent open_basedir restrictions. + if (!@move_uploaded_file($uploaded_file['tmp_name'], $pun_config['o_avatars_dir'].'/'.$id.'.tmp')) + message($lang_profile['Move failed'].' '.$pun_config['o_admin_email'].'.'); + + // Now check the width/height + list($width, $height, $type,) = getimagesize($pun_config['o_avatars_dir'].'/'.$id.'.tmp'); + if (empty($width) || empty($height) || $width > $pun_config['o_avatars_width'] || $height > $pun_config['o_avatars_height']) + { + @unlink($pun_config['o_avatars_dir'].'/'.$id.'.tmp'); + message($lang_profile['Too wide or high'].' '.$pun_config['o_avatars_width'].'x'.$pun_config['o_avatars_height'].' '.$lang_profile['pixels'].'.'); + } + else if ($type == 1 && $uploaded_file['type'] != 'image/gif') // Prevent dodgy uploads + { + @unlink($pun_config['o_avatars_dir'].'/'.$id.'.tmp'); + message($lang_profile['Bad type']); + } + + // Delete any old avatars and put the new one in place + @unlink($pun_config['o_avatars_dir'].'/'.$id.$extensions[0]); + @unlink($pun_config['o_avatars_dir'].'/'.$id.$extensions[1]); + @unlink($pun_config['o_avatars_dir'].'/'.$id.$extensions[2]); + @rename($pun_config['o_avatars_dir'].'/'.$id.'.tmp', $pun_config['o_avatars_dir'].'/'.$id.$extensions[0]); + @chmod($pun_config['o_avatars_dir'].'/'.$id.$extensions[0], 0644); + } + else + message($lang_profile['Unknown failure']); + + // Enable use_avatar (seems sane since the user just uploaded an avatar) + $db->query('UPDATE '.$db->prefix.'users SET use_avatar=1 WHERE id='.$id) or error('Unable to update avatar state', __FILE__, __LINE__, $db->error()); + + redirect('profile.php?section=personality&id='.$id, $lang_profile['Avatar upload redirect']); + } + + $page_title = pun_htmlspecialchars($pun_config['o_board_title']).' / '.$lang_common['Profile']; + $required_fields = array('req_file' => $lang_profile['File']); + $focus_element = array('upload_avatar', 'req_file'); + require PUN_ROOT.'header.php'; + +?> +
    +

    +
    +
    +
    +
    + +
    + + + +

    KB).

    +
    +
    +
    +

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

    +
    +
    +
    +
    + +
    +

    +
    + +
    +

    +
    +
    +
    +

    +
    +
    +
    +query('SELECT group_id 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']); + + $group_id = $db->result($result); + + if ($pun_user['id'] != $id && + ($pun_user['g_id'] > PUN_MOD || + ($pun_user['g_id'] == PUN_MOD && $pun_config['p_mod_edit_users'] == '0') || + ($pun_user['g_id'] == PUN_MOD && $group_id < PUN_GUEST))) + message($lang_common['No permission']); + + if ($pun_user['g_id'] < PUN_GUEST) + confirm_referrer('profile.php'); + + // Extract allowed elements from $_POST['form'] + function extract_elements($allowed_elements) + { + $form = array(); + + while (list($key, $value) = @each($_POST['form'])) + { + if (in_array($key, $allowed_elements)) + $form[$key] = $value; + } + + return $form; + } + + $username_updated = false; + + // Validate input depending on section + switch ($section) + { + case 'essentials': + { + $form = extract_elements(array('timezone', 'language')); + + if ($pun_user['g_id'] < PUN_GUEST) + { + $form['admin_note'] = trim($_POST['admin_note']); + + // Are we allowed to change usernames? + if ($pun_user['g_id'] == PUN_ADMIN || ($pun_user['g_id'] == PUN_MOD && $pun_config['p_mod_rename_users'] == '1')) + { + $form['username'] = trim($_POST['req_username']); + $old_username = trim($_POST['old_username']); + + if (strlen($form['username']) < 2) + message($lang_prof_reg['Username too short']); + else if (pun_strlen($form['username']) > 25) // This usually doesn't happen since the form element only accepts 25 characters + message($lang_common['Bad request']); + else if (!strcasecmp($form['username'], 'Guest') || !strcasecmp($form['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}/', $form['username'])) + message($lang_prof_reg['Username IP']); + else if (preg_match('#\[b\]|\[/b\]|\[u\]|\[/u\]|\[i\]|\[/i\]|\[color|\[/color\]|\[quote\]|\[quote=|\[/quote\]|\[code\]|\[/code\]|\[img\]|\[/img\]|\[url|\[/url\]|\[email|\[/email\]#i', $form['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=\''.$db->escape($form['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']); + + if ($form['username'] != $old_username) + $username_updated = true; + } + + // We only allow administrators to update the post count + if ($pun_user['g_id'] == PUN_ADMIN) + $form['num_posts'] = intval($_POST['num_posts']); + } + + if ($pun_config['o_regs_verify'] == '0' || $pun_user['g_id'] < PUN_GUEST) + { + require PUN_ROOT.'include/email.php'; + + // Validate the email-address + $form['email'] = strtolower(trim($_POST['req_email'])); + if (!is_valid_email($form['email'])) + message($lang_common['Invalid e-mail']); + } + + // Make sure we got a valid language string + if (isset($form['language'])) + { + $form['language'] = preg_replace('#[\.\\\/]#', '', $form['language']); + if (!file_exists(PUN_ROOT.'lang/'.$form['language'].'/common.php')) + message($lang_common['Bad request']); + } + + break; + } + + case 'personal': + { + $form = extract_elements(array('realname', 'url', 'location')); + + if ($pun_user['g_id'] == PUN_ADMIN) + $form['title'] = trim($_POST['title']); + else if ($pun_user['g_set_title'] == '1') + { + $form['title'] = trim($_POST['title']); + + if ($form['title'] != '') + { + // A list of words that the title may not contain + // If the language is English, there will be some duplicates, but it's not the end of the world + $forbidden = array('Member', 'Moderator', 'Administrator', 'Banned', 'Guest', $lang_common['Member'], $lang_common['Moderator'], $lang_common['Administrator'], $lang_common['Banned'], $lang_common['Guest']); + + if (in_array($form['title'], $forbidden)) + message($lang_profile['Forbidden title']); + } + } + + // Add http:// if the URL doesn't contain it already + if ($form['url'] != '' && strpos(strtolower($form['url']), 'http://') !== 0) + $form['url'] = 'http://'.$form['url']; + + break; + } + + case 'messaging': + { + $form = extract_elements(array('jabber', 'icq', 'msn', 'aim', 'yahoo')); + + // 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']); + + break; + } + + case 'personality': + { + $form = extract_elements(array('use_avatar')); + + // Clean up signature from POST + $form['signature'] = pun_linebreaks(trim($_POST['signature'])); + + // Validate signature + if (pun_strlen($form['signature']) > $pun_config['p_sig_length']) + message($lang_prof_reg['Sig too long'].' '.$pun_config['p_sig_length'].' '.$lang_prof_reg['characters'].'.'); + else if (substr_count($form['signature'], "\n") > ($pun_config['p_sig_lines']-1)) + message($lang_prof_reg['Sig too many lines'].' '.$pun_config['p_sig_lines'].' '.$lang_prof_reg['lines'].'.'); + else if ($form['signature'] && $pun_config['p_sig_all_caps'] == '0' && strtoupper($form['signature']) == $form['signature'] && $pun_user['g_id'] > PUN_MOD) + $form['signature'] = ucwords(strtolower($form['signature'])); + + // Validate BBCode syntax + if ($pun_config['p_sig_bbcode'] == '1' && strpos($form['signature'], '[') !== false && strpos($form['signature'], ']') !== false) + { + require PUN_ROOT.'include/parser.php'; + $form['signature'] = preparse_bbcode($form['signature'], $foo, true); + } + + if (!isset($form['use_avatar']) || $form['use_avatar'] != '1') $form['use_avatar'] = '0'; + + break; + } + + case 'display': + { + $form = extract_elements(array('disp_topics', 'disp_posts', 'show_smilies', 'show_img', 'show_img_sig', 'show_avatars', 'show_sig', 'style')); + + 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['show_smilies']) || $form['show_smilies'] != '1') $form['show_smilies'] = '0'; + if (!isset($form['show_img']) || $form['show_img'] != '1') $form['show_img'] = '0'; + if (!isset($form['show_img_sig']) || $form['show_img_sig'] != '1') $form['show_img_sig'] = '0'; + if (!isset($form['show_avatars']) || $form['show_avatars'] != '1') $form['show_avatars'] = '0'; + if (!isset($form['show_sig']) || $form['show_sig'] != '1') $form['show_sig'] = '0'; + + break; + } + + case 'privacy': + { + $form = extract_elements(array('email_setting', 'save_pass', 'notify_with_post')); + + $form['email_setting'] = intval($form['email_setting']); + if ($form['email_setting'] < 0 && $form['email_setting'] > 2) $form['email_setting'] = 1; + + if (!isset($form['save_pass']) || $form['save_pass'] != '1') $form['save_pass'] = '0'; + if (!isset($form['notify_with_post']) || $form['notify_with_post'] != '1') $form['notify_with_post'] = '0'; + + // If the save_pass setting has changed, we need to set a new cookie with the appropriate expire date + if ($pun_user['id'] == $id && $form['save_pass'] != $pun_user['save_pass']) + { + $result = $db->query('SELECT password FROM '.$db->prefix.'users WHERE id='.$id) or error('Unable to fetch user password hash', __FILE__, __LINE__, $db->error()); + pun_setcookie($id, $db->result($result), ($form['save_pass'] == '1') ? time() + 31536000 : 0); + } + + break; + } + + default: + message($lang_common['Bad request']); + } + + + // Singlequotes around non-empty values and NULL for empty values + $temp = array(); + while (list($key, $input) = @each($form)) + { + $value = ($input !== '') ? '\''.$db->escape($input).'\'' : 'NULL'; + + $temp[] = $key.'='.$value; + } + + if (empty($temp)) + message($lang_common['Bad request']); + + + $db->query('UPDATE '.$db->prefix.'users SET '.implode(',', $temp).' WHERE id='.$id) or error('Unable to update profile', __FILE__, __LINE__, $db->error()); + + // If we changed the username we have to update some stuff + if ($username_updated) + { + $db->query('UPDATE '.$db->prefix.'posts SET poster=\''.$db->escape($form['username']).'\' WHERE poster_id='.$id) or error('Unable to update posts', __FILE__, __LINE__, $db->error()); + $db->query('UPDATE '.$db->prefix.'topics SET poster=\''.$db->escape($form['username']).'\' WHERE poster=\''.$db->escape($old_username).'\'') or error('Unable to update topics', __FILE__, __LINE__, $db->error()); + $db->query('UPDATE '.$db->prefix.'topics SET last_poster=\''.$db->escape($form['username']).'\' WHERE last_poster=\''.$db->escape($old_username).'\'') or error('Unable to update topics', __FILE__, __LINE__, $db->error()); + $db->query('UPDATE '.$db->prefix.'forums SET last_poster=\''.$db->escape($form['username']).'\' WHERE last_poster=\''.$db->escape($old_username).'\'') or error('Unable to update forums', __FILE__, __LINE__, $db->error()); + $db->query('UPDATE '.$db->prefix.'online SET ident=\''.$db->escape($form['username']).'\' WHERE ident=\''.$db->escape($old_username).'\'') or error('Unable to update online list', __FILE__, __LINE__, $db->error()); + + // If the user is a moderator or an administrator we have to update the moderator lists + $result = $db->query('SELECT group_id FROM '.$db->prefix.'users WHERE id='.$id) or error('Unable to fetch user info', __FILE__, __LINE__, $db->error()); + $group_id = $db->result($result); + + if ($group_id < PUN_GUEST) + { + $result = $db->query('SELECT id, moderators FROM '.$db->prefix.'forums') or error('Unable to fetch forum list', __FILE__, __LINE__, $db->error()); + + while ($cur_forum = $db->fetch_assoc($result)) + { + $cur_moderators = ($cur_forum['moderators'] != '') ? unserialize($cur_forum['moderators']) : array(); + + if (in_array($id, $cur_moderators)) + { + unset($cur_moderators[$old_username]); + $cur_moderators[$form['username']] = $id; + ksort($cur_moderators); + + $db->query('UPDATE '.$db->prefix.'forums SET moderators=\''.$db->escape(serialize($cur_moderators)).'\' WHERE id='.$cur_forum['id']) or error('Unable to update forum', __FILE__, __LINE__, $db->error()); + } + } + } + } + + redirect('profile.php?section='.$section.'&id='.$id, $lang_profile['Profile redirect']); +} + + +$result = $db->query('SELECT u.username, u.email, u.title, u.realname, u.url, u.jabber, u.icq, u.msn, u.aim, u.yahoo, u.location, u.use_avatar, u.signature, u.disp_topics, u.disp_posts, u.email_setting, u.save_pass, u.notify_with_post, u.show_smilies, u.show_img, u.show_img_sig, u.show_avatars, u.show_sig, u.timezone, u.language, u.style, u.num_posts, u.last_post, u.registered, u.registration_ip, u.admin_note, g.g_id, g.g_user_title FROM '.$db->prefix.'users AS u LEFT JOIN '.$db->prefix.'groups AS g ON g.g_id=u.group_id WHERE u.id='.$id) or error('Unable to fetch user info', __FILE__, __LINE__, $db->error()); +if (!$db->num_rows($result)) + message($lang_common['Bad request']); + +$user = $db->fetch_assoc($result); + +$last_post = format_time($user['last_post']); + +if ($user['signature'] != '') +{ + require PUN_ROOT.'include/parser.php'; + $parsed_signature = parse_signature($user['signature']); +} + + +// View or edit? +if ($pun_user['id'] != $id && + ($pun_user['g_id'] > PUN_MOD || + ($pun_user['g_id'] == PUN_MOD && $pun_config['p_mod_edit_users'] == '0') || + ($pun_user['g_id'] == PUN_MOD && $user['g_id'] < PUN_GUEST))) +{ + if ($user['email_setting'] == '0' && !$pun_user['is_guest']) + $email_field = ''.$user['email'].''; + else if ($user['email_setting'] == '1' && !$pun_user['is_guest']) + $email_field = ''.$lang_common['Send e-mail'].''; + else + $email_field = $lang_profile['Private']; + + $user_title_field = get_title($user); + + if ($user['url'] != '') + { + $user['url'] = pun_htmlspecialchars($user['url']); + + if ($pun_config['o_censoring'] == '1') + $user['url'] = censor_words($user['url']); + + $url = ''.$user['url'].''; + } + else + $url = $lang_profile['Unknown']; + + if ($pun_config['o_avatars'] == '1') + { + if ($user['use_avatar'] == '1') + { + if ($img_size = @getimagesize($pun_config['o_avatars_dir'].'/'.$id.'.gif')) + $avatar_field = ''; + else if ($img_size = @getimagesize($pun_config['o_avatars_dir'].'/'.$id.'.jpg')) + $avatar_field = ''; + else if ($img_size = @getimagesize($pun_config['o_avatars_dir'].'/'.$id.'.png')) + $avatar_field = ''; + else + $avatar_field = $lang_profile['No avatar']; + } + else + $avatar_field = $lang_profile['No avatar']; + } + + $posts_field = ''; + if ($pun_config['o_show_post_count'] == '1' || $pun_user['g_id'] < PUN_GUEST) + $posts_field = $user['num_posts']; + if ($pun_user['g_search'] == '1') + $posts_field .= (($posts_field != '') ? ' - ' : '').''.$lang_profile['Show posts'].''; + + $page_title = pun_htmlspecialchars($pun_config['o_board_title']).' / '.$lang_common['Profile']; + define('PUN_ALLOW_INDEX', 1); + require PUN_ROOT.'header.php'; + +?> +
    +

    +
    +
    +
    +
    + +
    +
    +
    :
    +
    +
    :
    +
    +
    :
    +
    +
    :
    +
    +
    :
    +
     
    +
    :
    +
    +
    +
    +
    +
    +
    +
    +
    + +
    +
    +
    :
    +
    +
    :
    +
    +
    :
    +
    +
    :
    +
    +
    :
    +
    +
    +
    +
    +
    +
    +
    +
    + +
    +
    +
    :
    +
    +
    :
    +
    +
    +
    +
    +
    +
    +
    +
    + +
    +
    +
    :
    +
    +
    :
    +
    +
    :
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + +'."\n"; + else + $username_field = '

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

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

    '.$lang_common['Send e-mail'].'

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

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

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

    '.$lang_common['E-mail'].': '.$user['email'].' - '.$lang_profile['Change e-mail'].'

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

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

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

    '.$lang_common['Posts'].': '.$user['num_posts'].' - '.$lang_profile['Show posts'].'

    '."\n"; + else + $posts_field = '

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

    '."\n"; + + $page_title = pun_htmlspecialchars($pun_config['o_board_title']).' / '.$lang_common['Profile']; + $required_fields = array('req_username' => $lang_common['Username'], 'req_email' => $lang_common['E-mail']); + require PUN_ROOT.'header.php'; + + generate_profile_menu('essentials'); + +?> +
    +

    +
    +
    +
    +
    + +
    + + + PUN_MOD && $pun_config['p_mod_change_passwords'] == '1')): ?>

    +
    +
    +
    +
    +
    + +
    + +
    +
    +
    +
    +
    + +
    + +read()) !== false) + { + if ($entry != '.' && $entry != '..' && is_dir(PUN_ROOT.'lang/'.$entry) && file_exists(PUN_ROOT.'lang/'.$entry.'/common.php')) + $languages[] = $entry; + } + $d->close(); + + // Only display the language selection box if there's more than one language available + if (count($languages) > 1) + { + natsort($languages); + +?> + + +
    +
    +
    +
    +
    + +
    +

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

    +

    :

    + + +
    +
    +
    +

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

    '."\n"; + + $page_title = pun_htmlspecialchars($pun_config['o_board_title']).' / '.$lang_common['Profile']; + require PUN_ROOT.'header.php'; + + generate_profile_menu('personal'); + +?> +
    +

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

    +
    +
    +
    + +
    +

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

    +
    +
    +
    +'.$lang_profile['Change avatar'].''; + if ($img_size = @getimagesize($pun_config['o_avatars_dir'].'/'.$id.'.gif')) + $avatar_format = 'gif'; + else if ($img_size = @getimagesize($pun_config['o_avatars_dir'].'/'.$id.'.jpg')) + $avatar_format = 'jpg'; + else if ($img_size = @getimagesize($pun_config['o_avatars_dir'].'/'.$id.'.png')) + $avatar_format = 'png'; + else + $avatar_field = ''.$lang_profile['Upload avatar'].''; + + // Display the delete avatar link? + if ($img_size) + $avatar_field .= '   '.$lang_profile['Delete avatar'].''; + + if ($user['signature'] != '') + $signature_preview = '

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

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

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

    '."\n"; + + $page_title = pun_htmlspecialchars($pun_config['o_board_title']).' / '.$lang_common['Profile']; + require PUN_ROOT.'header.php'; + + generate_profile_menu('personality'); + + +?> +
    +

    +
    +
    +
    +
    +
    + +
    + alt="" /> +

    +
    + +
    +

    +
    +
    +
    +
    +
    + +
    +

    +
    + +
    + + +
    +
    +
    +

    +
    +
    +
    + +
    +

    +
    +
    +
    +read()) !== false) + { + if (substr($entry, strlen($entry)-4) == '.css') + $styles[] = substr($entry, 0, strlen($entry)-4); + } + $d->close(); + + // Only display the style selection box if there's more than one style available + if (count($styles) == 1) + echo "\t\t\t".'
    '."\n"; + else if (count($styles) > 1) + { + natsort($styles); + +?> +
    +
    + +
    + +
    +
    +
    + +
    +
    + +
    +

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

    +
    +
    +
    +

    +
    +
    +
    + +
    +

    +
    +
    +
    +
    + +
    + +

    +
    + + + +
    +

    +
    + +
    +

    +
    + +
    +
    +
    +
    +

    +
    +
    +
    + PUN_MOD || ($pun_user['g_id'] == PUN_MOD && $pun_config['p_mod_ban_users'] == '0')) + message($lang_common['Bad request']); + + $page_title = pun_htmlspecialchars($pun_config['o_board_title']).' / '.$lang_common['Profile']; + require PUN_ROOT.'header.php'; + + generate_profile_menu('admin'); + +?> +
    +

    +
    +
    +
    + +
    + + +
    +

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

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

    '.$cur_forum['cat_name'].'

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

    +
    +
    +
    +
    + +
    +

    +
    +
    +
    +

    +
    +
    +
    +query('SELECT 1 FROM '.$db->prefix.'users WHERE registration_ip=\''.get_remote_address().'\' AND registered>'.(time() - 3600)) or error('Unable to fetch user info', __FILE__, __LINE__, $db->error()); + + if ($db->num_rows($result)) + message('A new user was registered with the same IP address as you within the last hour. To prevent registration flooding, at least an hour has to pass between registrations from the same IP. Sorry for the inconvenience.'); + + + $username = pun_trim($_POST['req_username']); + $email1 = strtolower(trim($_POST['req_email1'])); + + if ($pun_config['o_regs_verify'] == '1') + { + $email2 = strtolower(trim($_POST['req_email2'])); + + $password1 = random_pass(8); + $password2 = $password1; + } + else + { + $password1 = trim($_POST['req_password1']); + $password2 = trim($_POST['req_password2']); + } + + // Convert multiple whitespace characters into one (to prevent people from registering with indistinguishable usernames) + $username = preg_replace('#\s+#s', ' ', $username); + + // Validate username and passwords + if (strlen($username) < 2) + message($lang_prof_reg['Username too short']); + else if (pun_strlen($username) > 25) // This usually doesn't happen since the form element only accepts 25 characters + message($lang_common['Bad request']); + else if (strlen($password1) < 4) + message($lang_prof_reg['Pass too short']); + else if ($password1 != $password2) + message($lang_prof_reg['Pass not match']); + 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 ((strpos($username, '[') !== false || strpos($username, ']') !== false) && strpos($username, '\'') !== false && strpos($username, '"') !== false) + message($lang_prof_reg['Username reserved chars']); + else if (preg_match('#\[b\]|\[/b\]|\[u\]|\[/u\]|\[i\]|\[/i\]|\[color|\[/color\]|\[quote\]|\[quote=|\[/quote\]|\[code\]|\[/code\]|\[img\]|\[/img\]|\[url|\[/url\]|\[email|\[/email\]#i', $username)) + message($lang_prof_reg['Username BBCode']); + + // Check username for any censored words + if ($pun_config['o_censoring'] == '1') + { + // If the censored username differs from the username + if (censor_words($username) != $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 UPPER(username)=UPPER(\''.$db->escape($username).'\') OR UPPER(username)=UPPER(\''.$db->escape(preg_replace('/[^\w]/', '', $username)).'\')') or error('Unable to fetch user info', __FILE__, __LINE__, $db->error()); + + if ($db->num_rows($result)) + { + $busy = $db->result($result); + message($lang_register['Username dupe 1'].' '.pun_htmlspecialchars($busy).'. '.$lang_register['Username dupe 2']); + } + + + // Validate e-mail + require PUN_ROOT.'include/email.php'; + + if (!is_valid_email($email1)) + message($lang_common['Invalid e-mail']); + else if ($pun_config['o_regs_verify'] == '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 ($pun_config['p_allow_banned_email'] == '0') + message($lang_prof_reg['Banned e-mail']); + + $banned_email = true; // Used later when we send an alert e-mail + } + else + $banned_email = false; + + // Check if someone else already has registered with that e-mail address + $dupe_list = array(); + + $result = $db->query('SELECT username FROM '.$db->prefix.'users WHERE email=\''.$email1.'\'') or error('Unable to fetch user info', __FILE__, __LINE__, $db->error()); + if ($db->num_rows($result)) + { + if ($pun_config['p_allow_dupe_email'] == '0') + message($lang_prof_reg['Dupe e-mail']); + + while ($cur_dupe = $db->fetch_assoc($result)) + $dupe_list[] = $cur_dupe['username']; + } + + // Make sure we got a valid language string + if (isset($_POST['language'])) + { + $language = preg_replace('#[\.\\\/]#', '', $_POST['language']); + if (!file_exists(PUN_ROOT.'lang/'.$language.'/common.php')) + message($lang_common['Bad request']); + } + else + $language = $pun_config['o_default_lang']; + + $timezone = round($_POST['timezone'], 1); + $save_pass = (!isset($_POST['save_pass']) || $_POST['save_pass'] != '1') ? '0' : '1'; + + $email_setting = intval($_POST['email_setting']); + if ($email_setting < 0 || $email_setting > 2) $email_setting = 1; + + // Insert the new user into the database. We do this now to get the last inserted id for later use. + $now = time(); + + $intial_group_id = ($pun_config['o_regs_verify'] == '0') ? $pun_config['o_default_user_group'] : PUN_UNVERIFIED; + $password_hash = pun_hash($password1); + + // Add the user + $db->query('INSERT INTO '.$db->prefix.'users (username, group_id, password, email, email_setting, save_pass, timezone, language, style, registered, registration_ip, last_visit) VALUES(\''.$db->escape($username).'\', '.$intial_group_id.', \''.$password_hash.'\', \''.$email1.'\', '.$email_setting.', '.$save_pass.', '.$timezone.' , \''.$db->escape($language).'\', \''.$pun_config['o_default_style'].'\', '.$now.', \''.get_remote_address().'\', '.$now.')') or error('Unable to create user', __FILE__, __LINE__, $db->error()); + $new_uid = $db->insert_id(); + + + // If we previously found out that the e-mail was banned + if ($banned_email && $pun_config['o_mailing_list'] != '') + { + $mail_subject = 'Alert - Banned e-mail detected'; + $mail_message = 'User \''.$username.'\' registered with banned e-mail address: '.$email1."\n\n".'User profile: '.$pun_config['o_base_url'].'/profile.php?id='.$new_uid."\n\n".'-- '."\n".'Forum Mailer'."\n".'(Do not reply to this message)'; + + pun_mail($pun_config['o_mailing_list'], $mail_subject, $mail_message); + } + + // If we previously found out that the e-mail was a dupe + if (!empty($dupe_list) && $pun_config['o_mailing_list'] != '') + { + $mail_subject = 'Alert - Duplicate e-mail detected'; + $mail_message = 'User \''.$username.'\' registered with an e-mail address that also belongs to: '.implode(', ', $dupe_list)."\n\n".'User profile: '.$pun_config['o_base_url'].'/profile.php?id='.$new_uid."\n\n".'-- '."\n".'Forum Mailer'."\n".'(Do not reply to this message)'; + + pun_mail($pun_config['o_mailing_list'], $mail_subject, $mail_message); + } + + // Should we alert people on the admin mailing list that a new user has registered? + if ($pun_config['o_regs_report'] == '1') + { + $mail_subject = 'Alert - New registration'; + $mail_message = 'User \''.$username.'\' registered in the forums at '.$pun_config['o_base_url']."\n\n".'User profile: '.$pun_config['o_base_url'].'/profile.php?id='.$new_uid."\n\n".'-- '."\n".'Forum Mailer'."\n".'(Do not reply to this message)'; + + pun_mail($pun_config['o_mailing_list'], $mail_subject, $mail_message); + } + + // Must the user verify the registration or do we log him/her in right now? + if ($pun_config['o_regs_verify'] == '1') + { + // Load the "welcome" template + $mail_tpl = trim(file_get_contents(PUN_ROOT.'lang/'.$pun_user['language'].'/mail_templates/welcome.tpl')); + + // The first row contains the subject + $first_crlf = strpos($mail_tpl, "\n"); + $mail_subject = trim(substr($mail_tpl, 8, $first_crlf-8)); + $mail_message = trim(substr($mail_tpl, $first_crlf)); + + $mail_subject = str_replace('', $pun_config['o_board_title'], $mail_subject); + $mail_message = str_replace('', $pun_config['o_base_url'].'/', $mail_message); + $mail_message = str_replace('', $username, $mail_message); + $mail_message = str_replace('', $password1, $mail_message); + $mail_message = str_replace('', $pun_config['o_base_url'].'/login.php', $mail_message); + $mail_message = str_replace('', $pun_config['o_board_title'].' '.$lang_common['Mailer'], $mail_message); + + pun_mail($email1, $mail_subject, $mail_message); + + message($lang_register['Reg e-mail'].' '.$pun_config['o_admin_email'].'.', true); + } + + pun_setcookie($new_uid, $password_hash, ($save_pass != '0') ? $now + 31536000 : 0); + + redirect('index.php', $lang_register['Reg complete']); +} + + +$page_title = pun_htmlspecialchars($pun_config['o_board_title']).' / '.$lang_register['Register']; +$required_fields = array('req_username' => $lang_common['Username'], 'req_password1' => $lang_common['Password'], 'req_password2' => $lang_prof_reg['Confirm pass'], 'req_email1' => $lang_common['E-mail'], 'req_email2' => $lang_common['E-mail'].' 2'); +$focus_element = array('register', 'req_username'); +require PUN_ROOT.'header.php'; + +?> +
    +

    +
    +
    +
    +
    +

    +

    +

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

    +
    +
    +
    +
    +
    + +
    +

    + + +
    +
    +
    +
    +
    + +
    + +read()) !== false) + { + if ($entry != '.' && $entry != '..' && is_dir(PUN_ROOT.'lang/'.$entry) && file_exists(PUN_ROOT.'lang/'.$entry.'/common.php')) + $languages[] = $entry; + } + $d->close(); + + // Only display the language selection box if there's more than one language available + if (count($languages) > 1) + { + +?> + + +
    +
    +
    +
    +
    + +
    +

    +
    + + + +
    +

    +
    + +
    +
    +
    +
    +

    +
    +
    +
    +query('SELECT search_data FROM '.$db->prefix.'search_cache WHERE id='.$search_id.' AND ident=\''.$db->escape($ident).'\'') or error('Unable to fetch search results', __FILE__, __LINE__, $db->error()); + if ($row = $db->fetch_assoc($result)) + { + $temp = unserialize($row['search_data']); + + $search_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? + $forum_sql = ($forum != -1 || ($forum == -1 && $pun_config['o_search_all_forums'] == '0')) ? ' AND t.forum_id = '.$forum : ''; + + if (!empty($author) || !empty($keywords)) + { + // If it's a search for keywords + if ($keywords) + { + $stopwords = (array)@file(PUN_ROOT.'lang/'.$pun_user['language'].'/stopwords.txt'); + $stopwords = array_map('trim', $stopwords); + + // Are we searching for multibyte charset text? + if ($multibyte) + { + // Strip out excessive whitespace + $keywords = trim(preg_replace('#\s+#', ' ', $keywords)); + + $keywords_array = explode(' ', $keywords); + } + else + { + // Filter out non-alphabetical chars + $noise_match = array('^', '$', '&', '(', ')', '<', '>', '`', '\'', '"', '|', ',', '@', '_', '?', '%', '~', '[', ']', '{', '}', ':', '\\', '/', '=', '#', '\'', ';', '!', '¤'); + $noise_replace = array(' ', ' ', ' ', ' ', ' ', ' ', ' ', '', '', ' ', ' ', ' ', ' ', '', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '' , ' ', ' ', ' ', ' ', ' ', ' ', ' '); + $keywords = str_replace($noise_match, $noise_replace, $keywords); + + // Strip out excessive whitespace + $keywords = trim(preg_replace('#\s+#', ' ', $keywords)); + + // Fill an array with all the words + $keywords_array = explode(' ', $keywords); + + if (empty($keywords_array)) + message($lang_search['No hits']); + + while (list($i, $word) = @each($keywords_array)) + { + $num_chars = pun_strlen($word); + + if ($num_chars < 3 || $num_chars > 20 || in_array($word, $stopwords)) + unset($keywords_array[$i]); + } + + // Should we search in message body or topic subject specifically? + $search_in_cond = ($search_in) ? (($search_in > 0) ? ' AND m.subject_match = 0' : ' AND m.subject_match = 1') : ''; + } + + $word_count = 0; + $match_type = 'and'; + $result_list = array(); + @reset($keywords_array); + while (list(, $cur_word) = @each($keywords_array)) + { + switch ($cur_word) + { + case 'and': + case 'or': + case 'not': + $match_type = $cur_word; + break; + + default: + { + // Are we searching for multibyte charset text? + if ($multibyte) + { + $cur_word = $db->escape('%'.str_replace('*', '', $cur_word).'%'); + $cur_word_like = ($db_type == 'pgsql') ? 'ILIKE \''.$cur_word.'\'' : 'LIKE \''.$cur_word.'\''; + + if ($search_in > 0) + $sql = 'SELECT id FROM '.$db->prefix.'posts WHERE message '.$cur_word_like; + else if ($search_in < 0) + $sql = 'SELECT p.id FROM '.$db->prefix.'posts AS p INNER JOIN '.$db->prefix.'topics AS t ON t.id=p.topic_id WHERE t.subject '.$cur_word_like.' GROUP BY p.id, t.id'; + else + $sql = 'SELECT p.id FROM '.$db->prefix.'posts AS p INNER JOIN '.$db->prefix.'topics AS t ON t.id=p.topic_id WHERE p.message '.$cur_word_like.' OR t.subject '.$cur_word_like.' GROUP BY p.id, t.id'; + } + else + { + $cur_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 \''.$cur_word.'\''.$search_in_cond; + } + + $result = $db->query($sql, true) or error('Unable to search for posts', __FILE__, __LINE__, $db->error()); + + $row = array(); + while ($temp = $db->fetch_row($result)) + { + $row[$temp[0]] = 1; + + if (!$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) + { + @reset($result_list); + while (list($post_id,) = @each($result_list)) + { + if (!isset($row[$post_id])) + $result_list[$post_id] = 0; + } + } + + ++$word_count; + $db->free_result($result); + + break; + } + } + } + + @reset($result_list); + while (list($post_id, $matches) = @each($result_list)) + { + 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 'pgsql': + $result = $db->query('SELECT id FROM '.$db->prefix.'users WHERE username ILIKE \''.$db->escape($author).'\'') or error('Unable to fetch users', __FILE__, __LINE__, $db->error()); + break; + + default: + $result = $db->query('SELECT id FROM '.$db->prefix.'users WHERE username LIKE \''.$db->escape($author).'\'') or error('Unable to fetch users', __FILE__, __LINE__, $db->error()); + break; + } + + if ($db->num_rows($result)) + { + $user_ids = ''; + 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') + { + $result = $db->query('SELECT t.id FROM '.$db->prefix.'posts AS p INNER JOIN '.$db->prefix.'topics AS t ON t.id=p.topic_id INNER JOIN '.$db->prefix.'forums AS f ON f.id=t.forum_id LEFT JOIN '.$db->prefix.'forum_perms AS fp ON (fp.forum_id=f.id AND fp.group_id='.$pun_user['g_id'].') WHERE (fp.read_forum IS NULL OR fp.read_forum=1) AND p.id IN('.implode(',', $search_ids).')'.$forum_sql.' GROUP BY t.id', true) 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 + { + $result = $db->query('SELECT p.id FROM '.$db->prefix.'posts AS p INNER JOIN '.$db->prefix.'topics AS t ON t.id=p.topic_id INNER JOIN '.$db->prefix.'forums AS f ON f.id=t.forum_id LEFT JOIN '.$db->prefix.'forum_perms AS fp ON (fp.forum_id=f.id AND fp.group_id='.$pun_user['g_id'].') WHERE (fp.read_forum IS NULL OR fp.read_forum=1) AND p.id IN('.implode(',', $search_ids).')'.$forum_sql, true) 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 ($action == 'show_new' || $action == 'show_24h' || $action == 'show_user' || $action == 'show_subscriptions' || $action == 'show_unanswered') + { + // If it's a search for new posts + if ($action == 'show_new') + { + if ($pun_user['is_guest']) + message($lang_common['No permission']); + + $result = $db->query('SELECT t.id FROM '.$db->prefix.'topics AS t INNER JOIN '.$db->prefix.'forums AS f ON f.id=t.forum_id LEFT JOIN '.$db->prefix.'forum_perms AS fp ON (fp.forum_id=f.id AND fp.group_id='.$pun_user['g_id'].') WHERE (fp.read_forum IS NULL OR fp.read_forum=1) AND t.last_post>'.$pun_user['last_visit'].' AND t.moved_to IS NULL') or error('Unable to fetch topic list', __FILE__, __LINE__, $db->error()); + $num_hits = $db->num_rows($result); + + if (!$num_hits) + message($lang_search['No new posts']); + } + // If it's a search for todays posts + else if ($action == 'show_24h') + { + $result = $db->query('SELECT t.id FROM '.$db->prefix.'topics AS t INNER JOIN '.$db->prefix.'forums AS f ON f.id=t.forum_id LEFT JOIN '.$db->prefix.'forum_perms AS fp ON (fp.forum_id=f.id AND fp.group_id='.$pun_user['g_id'].') WHERE (fp.read_forum IS NULL OR fp.read_forum=1) AND t.last_post>'.(time() - 86400).' AND t.moved_to IS NULL') or error('Unable to fetch topic list', __FILE__, __LINE__, $db->error()); + $num_hits = $db->num_rows($result); + + if (!$num_hits) + message($lang_search['No recent posts']); + } + // If it's a search for posts by a specific user ID + else if ($action == 'show_user') + { + $result = $db->query('SELECT t.id FROM '.$db->prefix.'topics AS t INNER JOIN '.$db->prefix.'posts AS p ON t.id=p.topic_id INNER JOIN '.$db->prefix.'forums AS f ON f.id=t.forum_id LEFT JOIN '.$db->prefix.'forum_perms AS fp ON (fp.forum_id=f.id AND fp.group_id='.$pun_user['g_id'].') WHERE (fp.read_forum IS NULL OR fp.read_forum=1) AND p.poster_id='.$user_id.' GROUP BY t.id') or error('Unable to fetch topic list', __FILE__, __LINE__, $db->error()); + $num_hits = $db->num_rows($result); + + if (!$num_hits) + message($lang_search['No user posts']); + } + // If it's a search for subscribed topics + else if ($action == 'show_subscriptions') + { + if ($pun_user['is_guest']) + message($lang_common['Bad request']); + + $result = $db->query('SELECT t.id FROM '.$db->prefix.'topics AS t INNER JOIN '.$db->prefix.'subscriptions AS s ON (t.id=s.topic_id AND s.user_id='.$pun_user['id'].') INNER JOIN '.$db->prefix.'forums AS f ON f.id=t.forum_id LEFT JOIN '.$db->prefix.'forum_perms AS fp ON (fp.forum_id=f.id AND fp.group_id='.$pun_user['g_id'].') WHERE (fp.read_forum IS NULL OR fp.read_forum=1)') or error('Unable to fetch topic list', __FILE__, __LINE__, $db->error()); + $num_hits = $db->num_rows($result); + + if (!$num_hits) + message($lang_search['No subscriptions']); + } + // If it's a search for unanswered posts + else + { + $result = $db->query('SELECT t.id FROM '.$db->prefix.'topics AS t INNER JOIN '.$db->prefix.'forums AS f ON f.id=t.forum_id LEFT JOIN '.$db->prefix.'forum_perms AS fp ON (fp.forum_id=f.id AND fp.group_id='.$pun_user['g_id'].') WHERE (fp.read_forum IS NULL OR fp.read_forum=1) AND t.num_replies=0 AND t.moved_to IS NULL') 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 + $old_searches = array(); + $result = $db->query('SELECT ident FROM '.$db->prefix.'online') or error('Unable to fetch online list', __FILE__, __LINE__, $db->error()); + + if ($db->num_rows($result)) + { + while ($row = $db->fetch_row($result)) + $old_searches[] = '\''.$db->escape($row[0]).'\''; + + $db->query('DELETE FROM '.$db->prefix.'search_cache WHERE ident NOT IN('.implode(',', $old_searches).')') or error('Unable to delete search results', __FILE__, __LINE__, $db->error()); + } + + // 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 = serialize($temp); + $search_id = mt_rand(1, 2147483647); + + $ident = ($pun_user['is_guest']) ? get_remote_address() : $pun_user['username']; + + $db->query('INSERT INTO '.$db->prefix.'search_cache (id, ident, search_data) VALUES('.$search_id.', \''.$db->escape($ident).'\', \''.$db->escape($temp).'\')') or error('Unable to insert search results', __FILE__, __LINE__, $db->error()); + + if ($action != 'show_new' && $action != 'show_24h') + { + $db->end_transaction(); + $db->close(); + + // Redirect the user to the cached result page + header('Location: search.php?search_id='.$search_id); + exit; + } + } + + + // Fetch results to display + if ($search_results != '') + { + switch ($sort_by) + { + case 1: + $sort_by_sql = ($show_as == 'topics') ? 't.poster' : 'p.poster'; + break; + + case 2: + $sort_by_sql = 't.subject'; + break; + + case 3: + $sort_by_sql = 't.forum_id'; + break; + + case 4: + $sort_by_sql = 't.last_post'; + break; + + default: + $sort_by_sql = ($show_as == 'topics') ? 't.posted' : 'p.posted'; + break; + } + + if ($show_as == 'posts') + { + $substr_sql = ($db_type != 'sqlite') ? 'SUBSTRING' : 'SUBSTR'; + $sql = 'SELECT p.id AS pid, p.poster AS pposter, p.posted AS pposted, p.poster_id, '.$substr_sql.'(p.message, 1, 1000) 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 t.id=p.topic_id WHERE p.id IN('.$search_results.') ORDER BY '.$sort_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.closed, t.forum_id FROM '.$db->prefix.'topics AS t WHERE t.id IN('.$search_results.') ORDER BY '.$sort_by_sql; + + + // Determine the topic or post offset (based on $_GET['p']) + $per_page = ($show_as == 'posts') ? $pun_user['disp_posts'] : $pun_user['disp_topics']; + $num_pages = ceil($num_hits / $per_page); + + $p = (!isset($_GET['p']) || $_GET['p'] <= 1 || $_GET['p'] > $num_pages) ? 1 : $_GET['p']; + $start_from = $per_page * ($p - 1); + + // Generate paging links + $paging_links = $lang_common['Pages'].': '.paginate($num_pages, $p, 'search.php?search_id='.$search_id); + + + $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 = pun_htmlspecialchars($pun_config['o_board_title']).' / '.$lang_search['Search results']; + require PUN_ROOT.'header.php'; + + +?> +
    +
    + +
    +
    + + +
    +

    +
    +
    + + + + + + + + + + +query('SELECT id, forum_name FROM '.$db->prefix.'forums') or error('Unable to fetch forum list', __FILE__, __LINE__, $db->error()); + + $forum_list = array(); + while ($forum_list[] = $db->fetch_row($result)) + ; + + // Finally, lets loop through the results and output them + for ($i = 0; $i < count($search_set); ++$i) + { + @reset($forum_list); + while (list(, $temp) = @each($forum_list)) + { + if ($temp[0] == $search_set[$i]['forum_id']) + $forum = ''.pun_htmlspecialchars($temp[1]).''; + } + + if ($pun_config['o_censoring'] == '1') + $search_set[$i]['subject'] = censor_words($search_set[$i]['subject']); + + + if ($show_as == 'posts') + { + $icon = '
    '.$lang_common['Normal icon'].'
    '."\n"; + $subject = ''.pun_htmlspecialchars($search_set[$i]['subject']).''; + + if (!$pun_user['is_guest'] && $search_set[$i]['last_post'] > $pun_user['last_visit']) + $icon = '
    '.$lang_common['New icon'].'
    '."\n"; + + + if ($pun_config['o_censoring'] == '1') + $search_set[$i]['message'] = censor_words($search_set[$i]['message']); + + $message = str_replace("\n", '
    ', pun_htmlspecialchars($search_set[$i]['message'])); + $pposter = pun_htmlspecialchars($search_set[$i]['pposter']); + + if ($search_set[$i]['poster_id'] > 1) + $pposter = ''.$pposter.''; + + if (pun_strlen($message) >= 1000) + $message .= ' …'; + + $vtpost1 = ($i == 0) ? ' vtp1' : ''; + + // Switch the background color for every message. + $bg_switch = ($bg_switch) ? $bg_switch = false : $bg_switch = true; + $vtbg = ($bg_switch) ? ' rowodd' : ' roweven'; + + +?> +
    +

     »  » 

    +
    +
    +
    +
    +
    +
    Replies:
    +
    +

    +
    +
    +
    +
    +

    +
    +
    +
    +
    +
    +
    +
    '.$lang_common['Normal icon'].'
    '."\n"; + + $icon_text = $lang_common['Normal icon']; + $item_status = ''; + $icon_type = 'icon'; + + + $subject = ''.pun_htmlspecialchars($search_set[$i]['subject']).''.$lang_common['by'].' '.pun_htmlspecialchars($search_set[$i]['poster']).''; + + if ($search_set[$i]['closed'] != '0') + { + $icon_text = $lang_common['Closed icon']; + $item_status = 'iclosed'; + } + + if (!$pun_user['is_guest'] && $search_set[$i]['last_post'] > $pun_user['last_visit']) + { + $icon_text .= ' '.$lang_common['New icon']; + $item_status .= ' inew'; + $icon_type = 'icon inew'; + $subject = ''.$subject.''; + $subject_new_posts = ''.$lang_common['New posts'].' ]'; + } + else + $subject_new_posts = null; + + $num_pages_topic = ceil(($search_set[$i]['num_replies'] + 1) / $pun_user['disp_posts']); + + if ($num_pages_topic > 1) + $subject_multipage = '[ '.paginate($num_pages_topic, -1, 'viewtopic.php?id='.$search_set[$i]['tid']).' ]'; + else + $subject_multipage = null; + + // Should we show the "New posts" and/or the multipage links? + if (!empty($subject_new_posts) || !empty($subject_multipage)) + { + $subject .= '  '.(!empty($subject_new_posts) ? $subject_new_posts : ''); + $subject .= !empty($subject_multipage) ? ' '.$subject_multipage : ''; + } + +?> + > + + + + + +'."\n\t\t\t".'
    +
    +
    +
    + +
    +
    +
    '.format_time($search_set[$i]['last_post']).' '.$lang_common['by'].' '.pun_htmlspecialchars($search_set[$i]['last_poster']) ?>
    '."\n\t\t".'
    '."\n\t".'
    '."\n".'
    '."\n\n"; + +?> +
    +
    + +
    +
    + +
    +

    +
    + +
    +
    +FIELDSET { + BORDER-STYLE: solid; + BORDER-WIDTH: 1px +} + +/****************************************************************/ +/* 5. VERTICAL AND PAGE SPACING */ +/****************************************************************/ + +/* 5.1 Page margins */ + +HTML, BODY {MARGIN: 0; PADDING: 0} +#punwrap {margin:12px 20px} + +/* 5.2 Creates vertical space between main board elements (Margins) */ + +DIV.blocktable, DIV.block, DIV.blockform, DIV.block2col, #postreview {MARGIN-BOTTOM: 12px} +#punindex DIV.blocktable, DIV.blockpost {MARGIN-BOTTOM: 6px} +DIV.block2col DIV.blockform, DIV.block2col DIV.block {MARGIN-BOTTOM: 0px} + +/* 5.3 Remove space above breadcrumbs, postlinks and pagelinks with a negative top margin */ + +DIV.linkst, DIV.linksb {MARGIN-TOP: -12px} +DIV.postlinksb {MARGIN-TOP: -6px} + +/* 5.4 Put a 12px gap above the board information box in index because the category tables only +have a 6px space beneath them */ + +#brdstats {MARGIN-TOP: 12px} + +/****************************************************************/ +/* 6. SPACING AROUND CONTENT */ +/****************************************************************/ + +/* 6.1 Default padding for main items */ + +DIV.block DIV.inbox, DIV.blockmenu DIV.inbox {PADDING: 3px 6px} +.pun P, .pun UL, .pun DL, DIV.blockmenu LI, .pun LABEL, #announce DIV.inbox DIV {PADDING: 3px 0} +.pun H2 {PADDING: 4px 6px} + +/* 6.2 Special spacing for various elements */ + +.pun H1 {PADDING: 3px 0px 0px 0} +#brdtitle P {PADDING-TOP: 0px} +DIV.linkst {PADDING: 8px 6px 3px 6px} +DIV.linksb, DIV.postlinksb {PADDING: 3px 6px 8px 6px} +#brdwelcome, #brdfooter DL A, DIV.blockmenu LI, DIV.rbox INPUT {LINE-HEIGHT: 1.4em} +#viewprofile DT, #viewprofile DD {PADDING: 0 3px; LINE-HEIGHT: 2em} + +/* 6.4 Create some horizontal spacing for various elements */ + +#brdmenu LI, DIV.rbox INPUT, DIV.blockform P INPUT {MARGIN-RIGHT: 12px} + +/****************************************************************/ +/* 7. SPACING FOR TABLES */ +/****************************************************************/ + +.pun TH, .pun TD {PADDING: 4px 6px} +.pun TD P {PADDING: 5px 0 0 0} + +/****************************************************************/ +/* 8. SPACING FOR POSTS */ +/****************************************************************/ + +/* 8.1 Padding around left and right columns in viewtopic */ + +DIV.postleft DL, DIV.postright {PADDING: 6px} + +/* 8.2 Extra spacing for poster contact details and avatar */ + +DD.usercontacts, DD.postavatar {MARGIN-TOP: 5px} +DD.postavatar {MARGIN-BOTTOM: 5px} + +/* 8.3 Extra top spacing for signatures and edited by */ + +DIV.postsignature, DIV.postmsg P.postedit {PADDING-TOP: 15px} + +/* 8.4 Spacing for code and quote boxes */ + +DIV.postmsg H4 {MARGIN-BOTTOM: 10px} +.pun BLOCKQUOTE, DIV.codebox {MARGIN: 5px 15px 15px 15px; PADDING: 8px} + +/* 8.5 Padding for the action links and online indicator in viewtopic */ + +DIV.postfootleft P, DIV.postfootright UL, DIV.postfootright DIV {PADDING: 10px 6px 5px 6px} + +/* 8.6 This is the input on moderators multi-delete view */ + +DIV.blockpost INPUT, DIV.blockpost LABEL { + PADDING: 3px; + DISPLAY: inline +} + +P.multidelete { + PADDING-TOP: 15px; + PADDING-BOTTOM: 5px +} + +/* 8.7 Make sure paragraphs in posts don't get any padding */ + +DIV.postmsg P {PADDING: 0} + +/****************************************************************/ +/* 9. SPECIAL SPACING FOR FORMS */ +/****************************************************************/ + +/* 9.1 Padding around fieldsets */ + +DIV.blockform FORM, DIV.fakeform {PADDING: 20px 20px 15px 20px} +DIV.inform {PADDING-BOTTOM: 12px} + +/* 9.2 Padding inside fieldsets */ + +.pun FIELDSET {PADDING: 0px 12px 0px 12px} +DIV.infldset {PADDING: 9px 0px 12px 0} +.pun LEGEND {PADDING: 0px 6px} + +/* 9.3 The information box at the top of the registration form and elsewhere */ + +DIV.forminfo { + MARGIN-BOTTOM: 12px; + PADDING: 9px 10px +} + +/* 9.4 BBCode help links in post forms */ + +UL.bblinks LI {PADDING-RIGHT: 20px} + +UL.bblinks {PADDING-BOTTOM: 10px; PADDING-LEFT: 4px} + +/* 9.5 Horizontal positioning for the submit button on forms */ + +DIV.blockform P INPUT {MARGIN-LEFT: 12px} + +/****************************************************************/ +/* 10. POST STATUS INDICATORS */ +/****************************************************************/ + +/* 10.1 These are the post status indicators which appear at the left of some tables. +.inew = new posts, .iredirect = redirect forums, .iclosed = closed topics and +.isticky = sticky topics. By default only .inew is different from the default.*/ + +DIV.icon { + FLOAT: left; + MARGIN-TOP: 0.1em; + MARGIN-LEFT: 0.2em; + DISPLAY: block; + BORDER-WIDTH: 0.6em 0.6em 0.6em 0.6em; + BORDER-STYLE: solid +} + +DIV.searchposts DIV.icon {MARGIN-LEFT: 0} + +/* 10.2 Class .tclcon is a div inside the first column of tables with post indicators. The +margin creates space for the post status indicator */ + +TD DIV.tclcon {MARGIN-LEFT: 2.3em} + + + + + + + + + + + diff -r 000000000000 -r f9ffdbd96607 punbb/style/Lithium.css --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/punbb/style/Lithium.css Wed Jul 11 21:01:48 2007 -0400 @@ -0,0 +1,258 @@ +/****************************************************************/ +/* 1. IMPORTED STYLESHEETS */ +/****************************************************************/ + +/* Import the basic setup styles */ +@import url(imports/base.css); +/* Import the colour scheme */ +@import url(imports/Lithium_cs.css); + +/****************************************************************/ +/* 2. TEXT SETTINGS */ +/****************************************************************/ + +/* 2.1 This sets the default Font Group */ + +.pun, .pun INPUT, .pun SELECT, .pun TEXTAREA, .pun OPTGROUP { + FONT-FAMILY: Verdana, Arial, Helvetica, sans-serif +} + +.pun {FONT-SIZE: 11px; LINE-HEIGHT: normal} + +/* IEWin Font Size only - to allow IEWin to zoom. Do not remove comments \*/ +* HTML .pun {FONT-SIZE: 68.75%} +/* End IE Win Font Size */ + +/* Set font size for tables because IE requires it */ +.pun TABLE, .pun INPUT, .pun SELECT, .pun OPTGROUP, .pun TEXTAREA, DIV.postmsg P.postedit {FONT-SIZE: 1em} + +/* 2.2 Set the font-size for preformatted text i.e in code boxes */ + +.pun PRE {FONT-FAMILY: monaco, "Bitstream Vera Sans Mono", "Courier New", courier, monospace} + +/* 2.3 Font size for headers */ + +.pun H2, .pun H4 {FONT-SIZE: 1em} +.pun H3 {FONT-SIZE: 1.1em} +#brdtitle H1 {FONT-SIZE: 1.4em} + +/* 2.4 Larger text for particular items */ +DIV.postmsg P {LINE-HEIGHT: 1.4} +DIV.postleft DT {FONT-SIZE: 1.1em} +.pun PRE {FONT-SIZE: 1.2em} + +/* 2.5 Bold text */ + +DIV.postleft DT, DIV.postmsg H4, TD.tcl H3, DIV.forminfo H3, P.postlink, DIV.linkst LI, +DIV.linksb LI, DIV.postlinksb LI, .blockmenu LI, #brdtitle H1, .pun SPAN.warntext, .pun P.warntext {FONT-WEIGHT: bold} + +/****************************************************************/ +/* 3. LINKS */ +/****************************************************************/ + +/* 3.1 Remove underlining for main menu, post header links, post links and vertical menus */ + +#brdmenu A:link, #brdmenu A:visited, .blockpost DT A:link, .blockpost DT A:visited, .blockpost H2 A:link, +.blockpost H2 A:visited, .postlink A:link, .postlink A:visited, .postfootright A:link, .postfootright A:visited, +.blockmenu A:link, .blockmenu A:visited { + TEXT-DECORATION: none +} + +/* 3.2 Underline on hover for links in headers and main menu */ + +#brdmenu A:hover, .blockpost H2 A:hover {TEXT-DECORATION: underline} + +/****************************************************************/ +/* 4. BORDER WIDTH AND STYLE */ +/****************************************************************/ + +/* 4.1 By default borders are 1px solid */ + +DIV.box, .pun TD, .pun TH, .pun BLOCKQUOTE, DIV.codebox, DIV.forminfo, DIV.blockpost LABEL { + BORDER-STYLE: solid; + BORDER-WIDTH: 1px +} + +/* 4.2 Special settings for the board header. */ + +#brdheader DIV.box {BORDER-TOP-WIDTH: 4px} + +/* 4.3 Borders for table cells */ + +.pun TD, .pun TH { + BORDER-BOTTOM: none; + BORDER-RIGHT: none +} + +.pun .tcl {BORDER-LEFT: none} + +/* 4.4 Special setting for fieldsets to preserve IE defaults */ + +DIV>FIELDSET { + BORDER-STYLE: solid; + BORDER-WIDTH: 1px +} + +/****************************************************************/ +/* 5. VERTICAL AND PAGE SPACING */ +/****************************************************************/ + +/* 5.1 Page margins */ + +HTML, BODY {MARGIN: 0; PADDING: 0} +#punwrap {margin:12px 20px} + +/* 5.2 Creates vertical space between main board elements (Margins) */ + +DIV.blocktable, DIV.block, DIV.blockform, DIV.block2col, #postreview {MARGIN-BOTTOM: 12px} +#punindex DIV.blocktable, DIV.blockpost {MARGIN-BOTTOM: 6px} +DIV.block2col DIV.blockform, DIV.block2col DIV.block {MARGIN-BOTTOM: 0px} + +/* 5.3 Remove space above breadcrumbs, postlinks and pagelinks with a negative top margin */ + +DIV.linkst, DIV.linksb {MARGIN-TOP: -12px} +DIV.postlinksb {MARGIN-TOP: -6px} + +/* 5.4 Put a 12px gap above the board information box in index because the category tables only +have a 6px space beneath them */ + +#brdstats {MARGIN-TOP: 12px} + +/****************************************************************/ +/* 6. SPACING AROUND CONTENT */ +/****************************************************************/ + +/* 6.1 Default padding for main items */ + +DIV.block DIV.inbox, DIV.blockmenu DIV.inbox {PADDING: 3px 6px} +.pun P, .pun UL, .pun DL, DIV.blockmenu LI, .pun LABEL, #announce DIV.inbox DIV {PADDING: 3px 0} +.pun H2 {PADDING: 4px 6px} + +/* 6.2 Special spacing for various elements */ + +.pun H1 {PADDING: 3px 0px 0px 0} +#brdtitle P {PADDING-TOP: 0px} +DIV.linkst {PADDING: 8px 6px 3px 6px} +DIV.linksb, DIV.postlinksb {PADDING: 3px 6px 8px 6px} +#brdwelcome, #brdfooter DL A, DIV.blockmenu LI, DIV.rbox INPUT {LINE-HEIGHT: 1.4em} +#viewprofile DT, #viewprofile DD {PADDING: 0 3px; LINE-HEIGHT: 2em} + +/* 6.4 Create some horizontal spacing for various elements */ + +#brdmenu LI, DIV.rbox INPUT, DIV.blockform P INPUT {MARGIN-RIGHT: 12px} + +/****************************************************************/ +/* 7. SPACING FOR TABLES */ +/****************************************************************/ + +.pun TH, .pun TD {PADDING: 4px 6px} +.pun TD P {PADDING: 5px 0 0 0} + +/****************************************************************/ +/* 8. SPACING FOR POSTS */ +/****************************************************************/ + +/* 8.1 Padding around left and right columns in viewtopic */ + +DIV.postleft DL, DIV.postright {PADDING: 6px} + +/* 8.2 Extra spacing for poster contact details and avatar */ + +DD.usercontacts, DD.postavatar {MARGIN-TOP: 5px} +DD.postavatar {MARGIN-BOTTOM: 5px} + +/* 8.3 Extra top spacing for signatures and edited by */ + +DIV.postsignature, DIV.postmsg P.postedit {PADDING-TOP: 15px} + +/* 8.4 Spacing for code and quote boxes */ + +DIV.postmsg H4 {MARGIN-BOTTOM: 10px} +.pun BLOCKQUOTE, DIV.codebox {MARGIN: 5px 15px 15px 15px; PADDING: 8px} + +/* 8.5 Padding for the action links and online indicator in viewtopic */ + +DIV.postfootleft P, DIV.postfootright UL, DIV.postfootright DIV {PADDING: 10px 6px 5px 6px} + +/* 8.6 This is the input on moderators multi-delete view */ + +DIV.blockpost INPUT, DIV.blockpost LABEL { + PADDING: 3px; + DISPLAY: inline +} + +P.multidelete { + PADDING-TOP: 15px; + PADDING-BOTTOM: 5px +} + +/* 8.7 Make sure paragraphs in posts don't get any padding */ + +DIV.postmsg P {PADDING: 0} + +/****************************************************************/ +/* 9. SPECIAL SPACING FOR FORMS */ +/****************************************************************/ + +/* 9.1 Padding around fieldsets */ + +DIV.blockform FORM, DIV.fakeform {PADDING: 20px 20px 15px 20px} +DIV.inform {PADDING-BOTTOM: 12px} + +/* 9.2 Padding inside fieldsets */ + +.pun FIELDSET {PADDING: 0px 12px 0px 12px} +DIV.infldset {PADDING: 9px 0px 12px 0} +.pun LEGEND {PADDING: 0px 6px} + +/* 9.3 The information box at the top of the registration form and elsewhere */ + +DIV.forminfo { + MARGIN-BOTTOM: 12px; + PADDING: 9px 10px +} + +/* 9.4 BBCode help links in post forms */ + +UL.bblinks LI {PADDING-RIGHT: 20px} + +UL.bblinks {PADDING-BOTTOM: 10px; PADDING-LEFT: 4px} + +/* 9.5 Horizontal positioning for the submit button on forms */ + +DIV.blockform P INPUT {MARGIN-LEFT: 12px} + +/****************************************************************/ +/* 10. POST STATUS INDICATORS */ +/****************************************************************/ + +/* 10.1 These are the post status indicators which appear at the left of some tables. +.inew = new posts, .iredirect = redirect forums, .iclosed = closed topics and +.isticky = sticky topics. By default only .inew is different from the default.*/ + +DIV.icon { + FLOAT: left; + MARGIN-TOP: 0.1em; + MARGIN-LEFT: 0.2em; + DISPLAY: block; + BORDER-WIDTH: 0.6em 0.6em 0.6em 0.6em; + BORDER-STYLE: solid +} + +DIV.searchposts DIV.icon {MARGIN-LEFT: 0} + +/* 10.2 Class .tclcon is a div inside the first column of tables with post indicators. The +margin creates space for the post status indicator */ + +TD DIV.tclcon {MARGIN-LEFT: 2.3em} + + + + + + + + + + + diff -r 000000000000 -r f9ffdbd96607 punbb/style/Mercury.css --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/punbb/style/Mercury.css Wed Jul 11 21:01:48 2007 -0400 @@ -0,0 +1,258 @@ +/****************************************************************/ +/* 1. IMPORTED STYLESHEETS */ +/****************************************************************/ + +/* Import the basic setup styles */ +@import url(imports/base.css); +/* Import the colour scheme */ +@import url(imports/Mercury_cs.css); + +/****************************************************************/ +/* 2. TEXT SETTINGS */ +/****************************************************************/ + +/* 2.1 This sets the default Font Group */ + +.pun, .pun INPUT, .pun SELECT, .pun TEXTAREA, .pun OPTGROUP { + FONT-FAMILY: Verdana, Arial, Helvetica, sans-serif +} + +.pun {FONT-SIZE: 11px; LINE-HEIGHT: normal} + +/* IEWin Font Size only - to allow IEWin to zoom. Do not remove comments \*/ +* HTML .pun {FONT-SIZE: 68.75%} +/* End IE Win Font Size */ + +/* Set font size for tables because IE requires it */ +.pun TABLE, .pun INPUT, .pun SELECT, .pun OPTGROUP, .pun TEXTAREA, DIV.postmsg P.postedit {FONT-SIZE: 1em} + +/* 2.2 Set the font-size for preformatted text i.e in code boxes */ + +.pun PRE {FONT-FAMILY: monaco, "Bitstream Vera Sans Mono", "Courier New", courier, monospace} + +/* 2.3 Font size for headers */ + +.pun H2, .pun H4 {FONT-SIZE: 1em} +.pun H3 {FONT-SIZE: 1.1em} +#brdtitle H1 {FONT-SIZE: 1.4em} + +/* 2.4 Larger text for particular items */ +DIV.postmsg P {LINE-HEIGHT: 1.4} +DIV.postleft DT {FONT-SIZE: 1.1em} +.pun PRE {FONT-SIZE: 1.2em} + +/* 2.5 Bold text */ + +DIV.postleft DT, DIV.postmsg H4, TD.tcl H3, DIV.forminfo H3, P.postlink, DIV.linkst LI, +DIV.linksb LI, DIV.postlinksb LI, .blockmenu LI, #brdtitle H1, .pun SPAN.warntext, .pun P.warntext {FONT-WEIGHT: bold} + +/****************************************************************/ +/* 3. LINKS */ +/****************************************************************/ + +/* 3.1 Remove underlining for main menu, post header links, post links and vertical menus */ + +#brdmenu A:link, #brdmenu A:visited, .blockpost DT A:link, .blockpost DT A:visited, .blockpost H2 A:link, +.blockpost H2 A:visited, .postlink A:link, .postlink A:visited, .postfootright A:link, .postfootright A:visited, +.blockmenu A:link, .blockmenu A:visited { + TEXT-DECORATION: none +} + +/* 3.2 Underline on hover for links in headers and main menu */ + +#brdmenu A:hover, .blockpost H2 A:hover {TEXT-DECORATION: underline} + +/****************************************************************/ +/* 4. BORDER WIDTH AND STYLE */ +/****************************************************************/ + +/* 4.1 By default borders are 1px solid */ + +DIV.box, .pun TD, .pun TH, .pun BLOCKQUOTE, DIV.codebox, DIV.forminfo, DIV.blockpost LABEL { + BORDER-STYLE: solid; + BORDER-WIDTH: 1px +} + +/* 4.2 Special settings for the board header. */ + +#brdheader DIV.box {BORDER-TOP-WIDTH: 4px} + +/* 4.3 Borders for table cells */ + +.pun TD, .pun TH { + BORDER-BOTTOM: none; + BORDER-RIGHT: none +} + +.pun .tcl {BORDER-LEFT: none} + +/* 4.4 Special setting for fieldsets to preserve IE defaults */ + +DIV>FIELDSET { + BORDER-STYLE: solid; + BORDER-WIDTH: 1px +} + +/****************************************************************/ +/* 5. VERTICAL AND PAGE SPACING */ +/****************************************************************/ + +/* 5.1 Page margins */ + +HTML, BODY {MARGIN: 0; PADDING: 0} +#punwrap {margin:12px 20px} + +/* 5.2 Creates vertical space between main board elements (Margins) */ + +DIV.blocktable, DIV.block, DIV.blockform, DIV.block2col, #postreview {MARGIN-BOTTOM: 12px} +#punindex DIV.blocktable, DIV.blockpost {MARGIN-BOTTOM: 6px} +DIV.block2col DIV.blockform, DIV.block2col DIV.block {MARGIN-BOTTOM: 0px} + +/* 5.3 Remove space above breadcrumbs, postlinks and pagelinks with a negative top margin */ + +DIV.linkst, DIV.linksb {MARGIN-TOP: -12px} +DIV.postlinksb {MARGIN-TOP: -6px} + +/* 5.4 Put a 12px gap above the board information box in index because the category tables only +have a 6px space beneath them */ + +#brdstats {MARGIN-TOP: 12px} + +/****************************************************************/ +/* 6. SPACING AROUND CONTENT */ +/****************************************************************/ + +/* 6.1 Default padding for main items */ + +DIV.block DIV.inbox, DIV.blockmenu DIV.inbox {PADDING: 3px 6px} +.pun P, .pun UL, .pun DL, DIV.blockmenu LI, .pun LABEL, #announce DIV.inbox DIV {PADDING: 3px 0} +.pun H2 {PADDING: 4px 6px} + +/* 6.2 Special spacing for various elements */ + +.pun H1 {PADDING: 3px 0px 0px 0} +#brdtitle P {PADDING-TOP: 0px} +DIV.linkst {PADDING: 8px 6px 3px 6px} +DIV.linksb, DIV.postlinksb {PADDING: 3px 6px 8px 6px} +#brdwelcome, #brdfooter DL A, DIV.blockmenu LI, DIV.rbox INPUT {LINE-HEIGHT: 1.4em} +#viewprofile DT, #viewprofile DD {PADDING: 0 3px; LINE-HEIGHT: 2em} + +/* 6.4 Create some horizontal spacing for various elements */ + +#brdmenu LI, DIV.rbox INPUT, DIV.blockform P INPUT {MARGIN-RIGHT: 12px} + +/****************************************************************/ +/* 7. SPACING FOR TABLES */ +/****************************************************************/ + +.pun TH, .pun TD {PADDING: 4px 6px} +.pun TD P {PADDING: 5px 0 0 0} + +/****************************************************************/ +/* 8. SPACING FOR POSTS */ +/****************************************************************/ + +/* 8.1 Padding around left and right columns in viewtopic */ + +DIV.postleft DL, DIV.postright {PADDING: 6px} + +/* 8.2 Extra spacing for poster contact details and avatar */ + +DD.usercontacts, DD.postavatar {MARGIN-TOP: 5px} +DD.postavatar {MARGIN-BOTTOM: 5px} + +/* 8.3 Extra top spacing for signatures and edited by */ + +DIV.postsignature, DIV.postmsg P.postedit {PADDING-TOP: 15px} + +/* 8.4 Spacing for code and quote boxes */ + +DIV.postmsg H4 {MARGIN-BOTTOM: 10px} +.pun BLOCKQUOTE, DIV.codebox {MARGIN: 5px 15px 15px 15px; PADDING: 8px} + +/* 8.5 Padding for the action links and online indicator in viewtopic */ + +DIV.postfootleft P, DIV.postfootright UL, DIV.postfootright DIV {PADDING: 10px 6px 5px 6px} + +/* 8.6 This is the input on moderators multi-delete view */ + +DIV.blockpost INPUT, DIV.blockpost LABEL { + PADDING: 3px; + DISPLAY: inline +} + +P.multidelete { + PADDING-TOP: 15px; + PADDING-BOTTOM: 5px +} + +/* 8.7 Make sure paragraphs in posts don't get any padding */ + +DIV.postmsg P {PADDING: 0} + +/****************************************************************/ +/* 9. SPECIAL SPACING FOR FORMS */ +/****************************************************************/ + +/* 9.1 Padding around fieldsets */ + +DIV.blockform FORM, DIV.fakeform {PADDING: 20px 20px 15px 20px} +DIV.inform {PADDING-BOTTOM: 12px} + +/* 9.2 Padding inside fieldsets */ + +.pun FIELDSET {PADDING: 0px 12px 0px 12px} +DIV.infldset {PADDING: 9px 0px 12px 0} +.pun LEGEND {PADDING: 0px 6px} + +/* 9.3 The information box at the top of the registration form and elsewhere */ + +DIV.forminfo { + MARGIN-BOTTOM: 12px; + PADDING: 9px 10px +} + +/* 9.4 BBCode help links in post forms */ + +UL.bblinks LI {PADDING-RIGHT: 20px} + +UL.bblinks {PADDING-BOTTOM: 10px; PADDING-LEFT: 4px} + +/* 9.5 Horizontal positioning for the submit button on forms */ + +DIV.blockform P INPUT {MARGIN-LEFT: 12px} + +/****************************************************************/ +/* 10. POST STATUS INDICATORS */ +/****************************************************************/ + +/* 10.1 These are the post status indicators which appear at the left of some tables. +.inew = new posts, .iredirect = redirect forums, .iclosed = closed topics and +.isticky = sticky topics. By default only .inew is different from the default.*/ + +DIV.icon { + FLOAT: left; + MARGIN-TOP: 0.1em; + MARGIN-LEFT: 0.2em; + DISPLAY: block; + BORDER-WIDTH: 0.6em 0.6em 0.6em 0.6em; + BORDER-STYLE: solid +} + +DIV.searchposts DIV.icon {MARGIN-LEFT: 0} + +/* 10.2 Class .tclcon is a div inside the first column of tables with post indicators. The +margin creates space for the post status indicator */ + +TD DIV.tclcon {MARGIN-LEFT: 2.3em} + + + + + + + + + + + diff -r 000000000000 -r f9ffdbd96607 punbb/style/Oxygen.css --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/punbb/style/Oxygen.css Wed Jul 11 21:01:48 2007 -0400 @@ -0,0 +1,258 @@ +/****************************************************************/ +/* 1. IMPORTED STYLESHEETS */ +/****************************************************************/ + +/* Import the basic setup styles */ +@import url(imports/base.css); +/* Import the colour scheme */ +@import url(imports/Oxygen_cs.css); + +/****************************************************************/ +/* 2. TEXT SETTINGS */ +/****************************************************************/ + +/* 2.1 This sets the default Font Group */ + +.pun, .pun INPUT, .pun SELECT, .pun TEXTAREA, .pun OPTGROUP { + FONT-FAMILY: Verdana, Arial, Helvetica, sans-serif +} + +.pun {FONT-SIZE: 11px; LINE-HEIGHT: normal} + +/* IEWin Font Size only - to allow IEWin to zoom. Do not remove comments \*/ +* HTML .pun {FONT-SIZE: 68.75%} +/* End IE Win Font Size */ + +/* Set font size for tables because IE requires it */ +.pun TABLE, .pun INPUT, .pun SELECT, .pun OPTGROUP, .pun TEXTAREA, DIV.postmsg P.postedit {FONT-SIZE: 1em} + +/* 2.2 Set the font-size for preformatted text i.e in code boxes */ + +.pun PRE {FONT-FAMILY: monaco, "Bitstream Vera Sans Mono", "Courier New", courier, monospace} + +/* 2.3 Font size for headers */ + +.pun H2, .pun H4 {FONT-SIZE: 1em} +.pun H3 {FONT-SIZE: 1.1em} +#brdtitle H1 {FONT-SIZE: 1.4em} + +/* 2.4 Larger text for particular items */ + DIV.postmsg P {LINE-HEIGHT: 1.4} +DIV.postleft DT {FONT-SIZE: 1.1em} +.pun PRE {FONT-SIZE: 1.2em} + +/* 2.5 Bold text */ + +DIV.postleft DT, DIV.postmsg H4, TD.tcl H3, DIV.forminfo H3, P.postlink, DIV.linkst LI, +DIV.linksb LI, DIV.postlinksb LI, .blockmenu LI, #brdtitle H1, .pun SPAN.warntext, .pun P.warntext {FONT-WEIGHT: bold} + +/****************************************************************/ +/* 3. LINKS */ +/****************************************************************/ + +/* 3.1 Remove underlining for main menu, post header links, post links and vertical menus */ + +#brdmenu A:link, #brdmenu A:visited, .blockpost DT A:link, .blockpost DT A:visited, .blockpost H2 A:link, +.blockpost H2 A:visited, .postlink A:link, .postlink A:visited, .postfootright A:link, .postfootright A:visited, +.blockmenu A:link, .blockmenu A:visited { + TEXT-DECORATION: none +} + +/* 3.2 Underline on hover for links in headers and main menu */ + +#brdmenu A:hover, .blockpost H2 A:hover {TEXT-DECORATION: underline} + +/****************************************************************/ +/* 4. BORDER WIDTH AND STYLE */ +/****************************************************************/ + +/* 4.1 By default borders are 1px solid */ + +DIV.box, .pun TD, .pun TH, .pun BLOCKQUOTE, DIV.codebox, DIV.forminfo, DIV.blockpost LABEL { + BORDER-STYLE: solid; + BORDER-WIDTH: 1px +} + +/* 4.2 Special settings for the board header. */ + +#brdheader DIV.box {BORDER-TOP-WIDTH: 4px} + +/* 4.3 Borders for table cells */ + +.pun TD, .pun TH { + BORDER-BOTTOM: none; + BORDER-RIGHT: none +} + +.pun .tcl {BORDER-LEFT: none} + +/* 4.4 Special setting for fieldsets to preserve IE defaults */ + +DIV>FIELDSET { + BORDER-STYLE: solid; + BORDER-WIDTH: 1px +} + +/****************************************************************/ +/* 5. VERTICAL AND PAGE SPACING */ +/****************************************************************/ + +/* 5.1 Page margins */ + +HTML, BODY {MARGIN: 0; PADDING: 0} +#punwrap {margin:12px 20px} + +/* 5.2 Creates vertical space between main board elements (Margins) */ + +DIV.blocktable, DIV.block, DIV.blockform, DIV.block2col, #postreview {MARGIN-BOTTOM: 12px} +#punindex DIV.blocktable, DIV.blockpost {MARGIN-BOTTOM: 6px} +DIV.block2col DIV.blockform, DIV.block2col DIV.block {MARGIN-BOTTOM: 0px} + +/* 5.3 Remove space above breadcrumbs, postlinks and pagelinks with a negative top margin */ + +DIV.linkst, DIV.linksb {MARGIN-TOP: -12px} +DIV.postlinksb {MARGIN-TOP: -6px} + +/* 5.4 Put a 12px gap above the board information box in index because the category tables only +have a 6px space beneath them */ + +#brdstats {MARGIN-TOP: 12px} + +/****************************************************************/ +/* 6. SPACING AROUND CONTENT */ +/****************************************************************/ + +/* 6.1 Default padding for main items */ + +DIV.block DIV.inbox, DIV.blockmenu DIV.inbox {PADDING: 3px 6px} +.pun P, .pun UL, .pun DL, DIV.blockmenu LI, .pun LABEL, #announce DIV.inbox DIV {PADDING: 3px 0} +.pun H2 {PADDING: 4px 6px} + +/* 6.2 Special spacing for various elements */ + +.pun H1 {PADDING: 3px 0px 0px 0} +#brdtitle P {PADDING-TOP: 0px} +DIV.linkst {PADDING: 8px 6px 3px 6px} +DIV.linksb, DIV.postlinksb {PADDING: 3px 6px 8px 6px} +#brdwelcome, #brdfooter DL A, DIV.blockmenu LI, DIV.rbox INPUT {LINE-HEIGHT: 1.4em} +#viewprofile DT, #viewprofile DD {PADDING: 0 3px; LINE-HEIGHT: 2em} + +/* 6.4 Create some horizontal spacing for various elements */ + +#brdmenu LI, DIV.rbox INPUT, DIV.blockform P INPUT {MARGIN-RIGHT: 12px} + +/****************************************************************/ +/* 7. SPACING FOR TABLES */ +/****************************************************************/ + +.pun TH, .pun TD {PADDING: 4px 6px} +.pun TD P {PADDING: 5px 0 0 0} + +/****************************************************************/ +/* 8. SPACING FOR POSTS */ +/****************************************************************/ + +/* 8.1 Padding around left and right columns in viewtopic */ + +DIV.postleft DL, DIV.postright {PADDING: 6px} + +/* 8.2 Extra spacing for poster contact details and avatar */ + +DD.usercontacts, DD.postavatar {MARGIN-TOP: 5px} +DD.postavatar {MARGIN-BOTTOM: 5px} + +/* 8.3 Extra top spacing for signatures and edited by */ + +DIV.postsignature, DIV.postmsg P.postedit {PADDING-TOP: 15px} + +/* 8.4 Spacing for code and quote boxes */ + +DIV.postmsg H4 {MARGIN-BOTTOM: 10px} +.pun BLOCKQUOTE, DIV.codebox {MARGIN: 5px 15px 15px 15px; PADDING: 8px} + +/* 8.5 Padding for the action links and online indicator in viewtopic */ + +DIV.postfootleft P, DIV.postfootright UL, DIV.postfootright DIV {PADDING: 10px 6px 5px 6px} + +/* 8.6 This is the input on moderators multi-delete view */ + +DIV.blockpost INPUT, DIV.blockpost LABEL { + PADDING: 3px; + DISPLAY: inline +} + +P.multidelete { + PADDING-TOP: 15px; + PADDING-BOTTOM: 5px +} + +/* 8.7 Make sure paragraphs in posts don't get any padding */ + +DIV.postmsg P {PADDING: 0} + +/****************************************************************/ +/* 9. SPECIAL SPACING FOR FORMS */ +/****************************************************************/ + +/* 9.1 Padding around fieldsets */ + +DIV.blockform FORM, DIV.fakeform {PADDING: 20px 20px 15px 20px} +DIV.inform {PADDING-BOTTOM: 12px} + +/* 9.2 Padding inside fieldsets */ + +.pun FIELDSET {PADDING: 0px 12px 0px 12px} +DIV.infldset {PADDING: 9px 0px 12px 0} +.pun LEGEND {PADDING: 0px 6px} + +/* 9.3 The information box at the top of the registration form and elsewhere */ + +DIV.forminfo { + MARGIN-BOTTOM: 12px; + PADDING: 9px 10px +} + +/* 9.4 BBCode help links in post forms */ + +UL.bblinks LI {PADDING-RIGHT: 20px} + +UL.bblinks {PADDING-BOTTOM: 10px; PADDING-LEFT: 4px} + +/* 9.5 Horizontal positioning for the submit button on forms */ + +DIV.blockform P INPUT {MARGIN-LEFT: 12px} + +/****************************************************************/ +/* 10. POST STATUS INDICATORS */ +/****************************************************************/ + +/* 10.1 These are the post status indicators which appear at the left of some tables. +.inew = new posts, .iredirect = redirect forums, .iclosed = closed topics and +.isticky = sticky topics. By default only .inew is different from the default.*/ + +DIV.icon { + FLOAT: left; + MARGIN-TOP: 0.1em; + MARGIN-LEFT: 0.2em; + DISPLAY: block; + BORDER-WIDTH: 0.6em 0.6em 0.6em 0.6em; + BORDER-STYLE: solid +} + +DIV.searchposts DIV.icon {MARGIN-LEFT: 0} + +/* 10.2 Class .tclcon is a div inside the first column of tables with post indicators. The +margin creates space for the post status indicator */ + +TD DIV.tclcon {MARGIN-LEFT: 2.3em} + + + + + + + + + + + diff -r 000000000000 -r f9ffdbd96607 punbb/style/Radium.css --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/punbb/style/Radium.css Wed Jul 11 21:01:48 2007 -0400 @@ -0,0 +1,258 @@ +/****************************************************************/ +/* 1. IMPORTED STYLESHEETS */ +/****************************************************************/ + +/* Import the basic setup styles */ +@import url(imports/base.css); +/* Import the colour scheme */ +@import url(imports/Radium_cs.css); + +/****************************************************************/ +/* 2. TEXT SETTINGS */ +/****************************************************************/ + +/* 2.1 This sets the default Font Group */ + +.pun, .pun INPUT, .pun SELECT, .pun TEXTAREA, .pun OPTGROUP { + FONT-FAMILY: Verdana, Arial, Helvetica, sans-serif +} + +.pun {FONT-SIZE: 11px; LINE-HEIGHT: normal} + +/* IEWin Font Size only - to allow IEWin to zoom. Do not remove comments \*/ +* HTML .pun {FONT-SIZE: 68.75%} +/* End IE Win Font Size */ + +/* Set font size for tables because IE requires it */ +.pun TABLE, .pun INPUT, .pun SELECT, .pun OPTGROUP, .pun TEXTAREA, DIV.postmsg P.postedit {FONT-SIZE: 1em} + +/* 2.2 Set the font-size for preformatted text i.e in code boxes */ + +.pun PRE {FONT-FAMILY: monaco, "Bitstream Vera Sans Mono", "Courier New", courier, monospace} + +/* 2.3 Font size for headers */ + +.pun H2, .pun H4 {FONT-SIZE: 1em} +.pun H3 {FONT-SIZE: 1.1em} +#brdtitle H1 {FONT-SIZE: 1.4em} + +/* 2.4 Larger text for particular items */ +DIV.postmsg P {LINE-HEIGHT: 1.4} +DIV.postleft DT {FONT-SIZE: 1.1em} +.pun PRE {FONT-SIZE: 1.2em} + +/* 2.5 Bold text */ + +DIV.postleft DT, DIV.postmsg H4, TD.tcl H3, DIV.forminfo H3, P.postlink, DIV.linkst LI, +DIV.linksb LI, DIV.postlinksb LI, .blockmenu LI, #brdtitle H1, .pun SPAN.warntext, .pun P.warntext {FONT-WEIGHT: bold} + +/****************************************************************/ +/* 3. LINKS */ +/****************************************************************/ + +/* 3.1 Remove underlining for main menu, post header links, post links and vertical menus */ + +#brdmenu A:link, #brdmenu A:visited, .blockpost DT A:link, .blockpost DT A:visited, .blockpost H2 A:link, +.blockpost H2 A:visited, .postlink A:link, .postlink A:visited, .postfootright A:link, .postfootright A:visited, +.blockmenu A:link, .blockmenu A:visited { + TEXT-DECORATION: none +} + +/* 3.2 Underline on hover for links in headers and main menu */ + +#brdmenu A:hover, .blockpost H2 A:hover {TEXT-DECORATION: underline} + +/****************************************************************/ +/* 4. BORDER WIDTH AND STYLE */ +/****************************************************************/ + +/* 4.1 By default borders are 1px solid */ + +DIV.box, .pun TD, .pun TH, .pun BLOCKQUOTE, DIV.codebox, DIV.forminfo, DIV.blockpost LABEL { + BORDER-STYLE: solid; + BORDER-WIDTH: 1px +} + +/* 4.2 Special settings for the board header. */ + +#brdheader DIV.box {BORDER-TOP-WIDTH: 4px} + +/* 4.3 Borders for table cells */ + +.pun TD, .pun TH { + BORDER-BOTTOM: none; + BORDER-RIGHT: none +} + +.pun .tcl {BORDER-LEFT: none} + +/* 4.4 Special setting for fieldsets to preserve IE defaults */ + +DIV>FIELDSET { + BORDER-STYLE: solid; + BORDER-WIDTH: 1px +} + +/****************************************************************/ +/* 5. VERTICAL AND PAGE SPACING */ +/****************************************************************/ + +/* 5.1 Page margins */ + +HTML, BODY {MARGIN: 0; PADDING: 0} +#punwrap {margin:12px 20px} + +/* 5.2 Creates vertical space between main board elements (Margins) */ + +DIV.blocktable, DIV.block, DIV.blockform, DIV.block2col, #postreview {MARGIN-BOTTOM: 12px} +#punindex DIV.blocktable, DIV.blockpost {MARGIN-BOTTOM: 6px} +DIV.block2col DIV.blockform, DIV.block2col DIV.block {MARGIN-BOTTOM: 0px} + +/* 5.3 Remove space above breadcrumbs, postlinks and pagelinks with a negative top margin */ + +DIV.linkst, DIV.linksb {MARGIN-TOP: -12px} +DIV.postlinksb {MARGIN-TOP: -6px} + +/* 5.4 Put a 12px gap above the board information box in index because the category tables only +have a 6px space beneath them */ + +#brdstats {MARGIN-TOP: 12px} + +/****************************************************************/ +/* 6. SPACING AROUND CONTENT */ +/****************************************************************/ + +/* 6.1 Default padding for main items */ + +DIV.block DIV.inbox, DIV.blockmenu DIV.inbox {PADDING: 3px 6px} +.pun P, .pun UL, .pun DL, DIV.blockmenu LI, .pun LABEL, #announce DIV.inbox DIV {PADDING: 3px 0} +.pun H2 {PADDING: 4px 6px} + +/* 6.2 Special spacing for various elements */ + +.pun H1 {PADDING: 3px 0px 0px 0} +#brdtitle P {PADDING-TOP: 0px} +DIV.linkst {PADDING: 8px 6px 3px 6px} +DIV.linksb, DIV.postlinksb {PADDING: 3px 6px 8px 6px} +#brdwelcome, #brdfooter DL A, DIV.blockmenu LI, DIV.rbox INPUT {LINE-HEIGHT: 1.4em} +#viewprofile DT, #viewprofile DD {PADDING: 0 3px; LINE-HEIGHT: 2em} + +/* 6.4 Create some horizontal spacing for various elements */ + +#brdmenu LI, DIV.rbox INPUT, DIV.blockform P INPUT {MARGIN-RIGHT: 12px} + +/****************************************************************/ +/* 7. SPACING FOR TABLES */ +/****************************************************************/ + +.pun TH, .pun TD {PADDING: 4px 6px} +.pun TD P {PADDING: 5px 0 0 0} + +/****************************************************************/ +/* 8. SPACING FOR POSTS */ +/****************************************************************/ + +/* 8.1 Padding around left and right columns in viewtopic */ + +DIV.postleft DL, DIV.postright {PADDING: 6px} + +/* 8.2 Extra spacing for poster contact details and avatar */ + +DD.usercontacts, DD.postavatar {MARGIN-TOP: 5px} +DD.postavatar {MARGIN-BOTTOM: 5px} + +/* 8.3 Extra top spacing for signatures and edited by */ + +DIV.postsignature, DIV.postmsg P.postedit {PADDING-TOP: 15px} + +/* 8.4 Spacing for code and quote boxes */ + +DIV.postmsg H4 {MARGIN-BOTTOM: 10px} +.pun BLOCKQUOTE, DIV.codebox {MARGIN: 5px 15px 15px 15px; PADDING: 8px} + +/* 8.5 Padding for the action links and online indicator in viewtopic */ + +DIV.postfootleft P, DIV.postfootright UL, DIV.postfootright DIV {PADDING: 10px 6px 5px 6px} + +/* 8.6 This is the input on moderators multi-delete view */ + +DIV.blockpost INPUT, DIV.blockpost LABEL { + PADDING: 3px; + DISPLAY: inline +} + +P.multidelete { + PADDING-TOP: 15px; + PADDING-BOTTOM: 5px +} + +/* 8.7 Make sure paragraphs in posts don't get any padding */ + +DIV.postmsg P {PADDING: 0} + +/****************************************************************/ +/* 9. SPECIAL SPACING FOR FORMS */ +/****************************************************************/ + +/* 9.1 Padding around fieldsets */ + +DIV.blockform FORM, DIV.fakeform {PADDING: 20px 20px 15px 20px} +DIV.inform {PADDING-BOTTOM: 12px} + +/* 9.2 Padding inside fieldsets */ + +.pun FIELDSET {PADDING: 0px 12px 0px 12px} +DIV.infldset {PADDING: 9px 0px 12px 0} +.pun LEGEND {PADDING: 0px 6px} + +/* 9.3 The information box at the top of the registration form and elsewhere */ + +DIV.forminfo { + MARGIN-BOTTOM: 12px; + PADDING: 9px 10px +} + +/* 9.4 BBCode help links in post forms */ + +UL.bblinks LI {PADDING-RIGHT: 20px} + +UL.bblinks {PADDING-BOTTOM: 10px; PADDING-LEFT: 4px} + +/* 9.5 Horizontal positioning for the submit button on forms */ + +DIV.blockform P INPUT {MARGIN-LEFT: 12px} + +/****************************************************************/ +/* 10. POST STATUS INDICATORS */ +/****************************************************************/ + +/* 10.1 These are the post status indicators which appear at the left of some tables. +.inew = new posts, .iredirect = redirect forums, .iclosed = closed topics and +.isticky = sticky topics. By default only .inew is different from the default.*/ + +DIV.icon { + FLOAT: left; + MARGIN-TOP: 0.1em; + MARGIN-LEFT: 0.2em; + DISPLAY: block; + BORDER-WIDTH: 0.6em 0.6em 0.6em 0.6em; + BORDER-STYLE: solid +} + +DIV.searchposts DIV.icon {MARGIN-LEFT: 0} + +/* 10.2 Class .tclcon is a div inside the first column of tables with post indicators. The +margin creates space for the post status indicator */ + +TD DIV.tclcon {MARGIN-LEFT: 2.3em} + + + + + + + + + + + diff -r 000000000000 -r f9ffdbd96607 punbb/style/Sulfur.css --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/punbb/style/Sulfur.css Wed Jul 11 21:01:48 2007 -0400 @@ -0,0 +1,258 @@ +/****************************************************************/ +/* 1. IMPORTED STYLESHEETS */ +/****************************************************************/ + +/* Import the basic setup styles */ +@import url(imports/base.css); +/* Import the colour scheme */ +@import url(imports/Sulfur_cs.css); + +/****************************************************************/ +/* 2. TEXT SETTINGS */ +/****************************************************************/ + +/* 2.1 This sets the default Font Group */ + +.pun, .pun INPUT, .pun SELECT, .pun TEXTAREA, .pun OPTGROUP { + FONT-FAMILY: Verdana, Arial, Helvetica, sans-serif +} + +.pun {FONT-SIZE: 11px; LINE-HEIGHT: normal} + +/* IEWin Font Size only - to allow IEWin to zoom. Do not remove comments \*/ +* HTML .pun {FONT-SIZE: 68.75%} +/* End IE Win Font Size */ + +/* Set font size for tables because IE requires it */ +.pun TABLE, .pun INPUT, .pun SELECT, .pun OPTGROUP, .pun TEXTAREA, DIV.postmsg P.postedit {FONT-SIZE: 1em} + +/* 2.2 Set the font-size for preformatted text i.e in code boxes */ + +.pun PRE {FONT-FAMILY: monaco, "Bitstream Vera Sans Mono", "Courier New", courier, monospace} + +/* 2.3 Font size for headers */ + +.pun H2, .pun H4 {FONT-SIZE: 1em} +.pun H3 {FONT-SIZE: 1.1em} +#brdtitle H1 {FONT-SIZE: 1.4em} + +/* 2.4 Larger text for particular items */ +DIV.postmsg P {LINE-HEIGHT: 1.4} +DIV.postleft DT {FONT-SIZE: 1.1em} +.pun PRE {FONT-SIZE: 1.2em} + +/* 2.5 Bold text */ + +DIV.postleft DT, DIV.postmsg H4, TD.tcl H3, DIV.forminfo H3, P.postlink, DIV.linkst LI, +DIV.linksb LI, DIV.postlinksb LI, .blockmenu LI, #brdtitle H1, .pun SPAN.warntext, .pun P.warntext {FONT-WEIGHT: bold} + +/****************************************************************/ +/* 3. LINKS */ +/****************************************************************/ + +/* 3.1 Remove underlining for main menu, post header links, post links and vertical menus */ + +#brdmenu A:link, #brdmenu A:visited, .blockpost DT A:link, .blockpost DT A:visited, .blockpost H2 A:link, +.blockpost H2 A:visited, .postlink A:link, .postlink A:visited, .postfootright A:link, .postfootright A:visited, +.blockmenu A:link, .blockmenu A:visited { + TEXT-DECORATION: none +} + +/* 3.2 Underline on hover for links in headers and main menu */ + +#brdmenu A:hover, .blockpost H2 A:hover {TEXT-DECORATION: underline} + +/****************************************************************/ +/* 4. BORDER WIDTH AND STYLE */ +/****************************************************************/ + +/* 4.1 By default borders are 1px solid */ + +DIV.box, .pun TD, .pun TH, .pun BLOCKQUOTE, DIV.codebox, DIV.forminfo, DIV.blockpost LABEL { + BORDER-STYLE: solid; + BORDER-WIDTH: 1px +} + +/* 4.2 Special settings for the board header. */ + +#brdheader DIV.box {BORDER-TOP-WIDTH: 4px} + +/* 4.3 Borders for table cells */ + +.pun TD, .pun TH { + BORDER-BOTTOM: none; + BORDER-RIGHT: none +} + +.pun .tcl {BORDER-LEFT: none} + +/* 4.4 Special setting for fieldsets to preserve IE defaults */ + +DIV>FIELDSET { + BORDER-STYLE: solid; + BORDER-WIDTH: 1px +} + +/****************************************************************/ +/* 5. VERTICAL AND PAGE SPACING */ +/****************************************************************/ + +/* 5.1 Page margins */ + +HTML, BODY {MARGIN: 0; PADDING: 0} +#punwrap {margin:12px 20px} + +/* 5.2 Creates vertical space between main board elements (Margins) */ + +DIV.blocktable, DIV.block, DIV.blockform, DIV.block2col, #postreview {MARGIN-BOTTOM: 12px} +#punindex DIV.blocktable, DIV.blockpost {MARGIN-BOTTOM: 6px} +DIV.block2col DIV.blockform, DIV.block2col DIV.block {MARGIN-BOTTOM: 0px} + +/* 5.3 Remove space above breadcrumbs, postlinks and pagelinks with a negative top margin */ + +DIV.linkst, DIV.linksb {MARGIN-TOP: -12px} +DIV.postlinksb {MARGIN-TOP: -6px} + +/* 5.4 Put a 12px gap above the board information box in index because the category tables only +have a 6px space beneath them */ + +#brdstats {MARGIN-TOP: 12px} + +/****************************************************************/ +/* 6. SPACING AROUND CONTENT */ +/****************************************************************/ + +/* 6.1 Default padding for main items */ + +DIV.block DIV.inbox, DIV.blockmenu DIV.inbox {PADDING: 3px 6px} +.pun P, .pun UL, .pun DL, DIV.blockmenu LI, .pun LABEL, #announce DIV.inbox DIV {PADDING: 3px 0} +.pun H2 {PADDING: 4px 6px} + +/* 6.2 Special spacing for various elements */ + +.pun H1 {PADDING: 3px 0px 0px 0} +#brdtitle P {PADDING-TOP: 0px} +DIV.linkst {PADDING: 8px 6px 3px 6px} +DIV.linksb, DIV.postlinksb {PADDING: 3px 6px 8px 6px} +#brdwelcome, #brdfooter DL A, DIV.blockmenu LI, DIV.rbox INPUT {LINE-HEIGHT: 1.4em} +#viewprofile DT, #viewprofile DD {PADDING: 0 3px; LINE-HEIGHT: 2em} + +/* 6.4 Create some horizontal spacing for various elements */ + +#brdmenu LI, DIV.rbox INPUT, DIV.blockform P INPUT {MARGIN-RIGHT: 12px} + +/****************************************************************/ +/* 7. SPACING FOR TABLES */ +/****************************************************************/ + +.pun TH, .pun TD {PADDING: 4px 6px} +.pun TD P {PADDING: 5px 0 0 0} + +/****************************************************************/ +/* 8. SPACING FOR POSTS */ +/****************************************************************/ + +/* 8.1 Padding around left and right columns in viewtopic */ + +DIV.postleft DL, DIV.postright {PADDING: 6px} + +/* 8.2 Extra spacing for poster contact details and avatar */ + +DD.usercontacts, DD.postavatar {MARGIN-TOP: 5px} +DD.postavatar {MARGIN-BOTTOM: 5px} + +/* 8.3 Extra top spacing for signatures and edited by */ + +DIV.postsignature, DIV.postmsg P.postedit {PADDING-TOP: 15px} + +/* 8.4 Spacing for code and quote boxes */ + +DIV.postmsg H4 {MARGIN-BOTTOM: 10px} +.pun BLOCKQUOTE, DIV.codebox {MARGIN: 5px 15px 15px 15px; PADDING: 8px} + +/* 8.5 Padding for the action links and online indicator in viewtopic */ + +DIV.postfootleft P, DIV.postfootright UL, DIV.postfootright DIV {PADDING: 10px 6px 5px 6px} + +/* 8.6 This is the input on moderators multi-delete view */ + +DIV.blockpost INPUT, DIV.blockpost LABEL { + PADDING: 3px; + DISPLAY: inline +} + +P.multidelete { + PADDING-TOP: 15px; + PADDING-BOTTOM: 5px +} + +/* 8.7 Make sure paragraphs in posts don't get any padding */ + +DIV.postmsg P {PADDING: 0} + +/****************************************************************/ +/* 9. SPECIAL SPACING FOR FORMS */ +/****************************************************************/ + +/* 9.1 Padding around fieldsets */ + +DIV.blockform FORM, DIV.fakeform {PADDING: 20px 20px 15px 20px} +DIV.inform {PADDING-BOTTOM: 12px} + +/* 9.2 Padding inside fieldsets */ + +.pun FIELDSET {PADDING: 0px 12px 0px 12px} +DIV.infldset {PADDING: 9px 0px 12px 0} +.pun LEGEND {PADDING: 0px 6px} + +/* 9.3 The information box at the top of the registration form and elsewhere */ + +DIV.forminfo { + MARGIN-BOTTOM: 12px; + PADDING: 9px 10px +} + +/* 9.4 BBCode help links in post forms */ + +UL.bblinks LI {PADDING-RIGHT: 20px} + +UL.bblinks {PADDING-BOTTOM: 10px; PADDING-LEFT: 4px} + +/* 9.5 Horizontal positioning for the submit button on forms */ + +DIV.blockform P INPUT {MARGIN-LEFT: 12px} + +/****************************************************************/ +/* 10. POST STATUS INDICATORS */ +/****************************************************************/ + +/* 10.1 These are the post status indicators which appear at the left of some tables. +.inew = new posts, .iredirect = redirect forums, .iclosed = closed topics and +.isticky = sticky topics. By default only .inew is different from the default.*/ + +DIV.icon { + FLOAT: left; + MARGIN-TOP: 0.1em; + MARGIN-LEFT: 0.2em; + DISPLAY: block; + BORDER-WIDTH: 0.6em 0.6em 0.6em 0.6em; + BORDER-STYLE: solid +} + +DIV.searchposts DIV.icon {MARGIN-LEFT: 0} + +/* 10.2 Class .tclcon is a div inside the first column of tables with post indicators. The +margin creates space for the post status indicator */ + +TD DIV.tclcon {MARGIN-LEFT: 2.3em} + + + + + + + + + + + diff -r 000000000000 -r f9ffdbd96607 punbb/style/imports/Cobalt_cs.css --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/punbb/style/imports/Cobalt_cs.css Wed Jul 11 21:01:48 2007 -0400 @@ -0,0 +1,117 @@ +/****************************************************************/ +/* 1. BACKGROUND AND TEXT COLOURS */ +/****************************************************************/ + +/* 1.1 Default background colour and text colour */ + +BODY {BACKGROUND-COLOR: #2A2A2A} + +.pun {COLOR: #D4D4D4} + +DIV.box, #adminconsole FIELDSET TH, .rowodd, .roweven {BACKGROUND-COLOR: #383838} +#adminconsole TD, #adminconsole TH {BORDER-COLOR: #383838} + +/* 1. 2 Darker background colours */ + +TD.tc2, TD.tc3, TD.tcmod, #brdfooter DIV.box {BACKGROUND-COLOR: #424242} +#adminconsole FIELDSET TD, #viewprofile DD, DIV.forminfo, DIV.blockmenu DIV.box, #adstats DD {BACKGROUND-COLOR: #484848} + +.pun BLOCKQUOTE, DIV.codebox {BACKGROUND-COLOR: #353533} + +/* 1.3 Main headers and navigation bar background and text colour */ + +.pun H2, #brdmenu {BACKGROUND-COLOR: #565656; COLOR: #D4D4D4} + +/* 1.4 Table header rows */ + +.pun TH, .bgc4 {BACKGROUND-COLOR: #484848} + +/* 1.5 Fieldset legend text colour */ + +.pun LEGEND {COLOR: #60A0DC} + +/* 1.6 Highlighted text for various items */ + +.pun DIV.blockmenu LI.isactive A, #posterror LI STRONG {COLOR: #D4D4D4} + +/* 1.7 Dark background for form elements */ + +.pun TEXTAREA, .pun INPUT, .pun SELECT {BACKGROUND-COLOR: #2A2A2A; COLOR: #D4D4D4} + +/****************************************************************/ +/* 2. POST BACKGROUNDS AND TEXT */ +/****************************************************************/ + +/* 2.1 This is the setup for posts. */ + +DIV.blockpost DIV.box, DIV.postright, DIV.postfootright, #postpreview {BACKGROUND-COLOR: #383838} +DIV.postright, DIV.postfootright {BORDER-LEFT-COLOR: #424242} +DIV.postleft, DIV.postfootleft, DIV.blockpost LABEL {BACKGROUND-COLOR: #424242} + +/* 2.2 Background for post headers and text colour for post numbers in viewtopic */ + +DIV.blockpost H2 {BACKGROUND-COLOR: #565656} +DIV.blockpost H2 SPAN.conr {COLOR: #A19E96} + +/* 2.3 This is the line above the signature in posts. Colour and background should be the same */ + +.pun HR {BACKGROUND-COLOR: #606060; COLOR: #606060} + +/****************************************************************/ +/* 3. BORDER COLOURS */ +/****************************************************************/ + +/* 3.1 All external borders (H1 is the board title) */ + +DIV.box {BORDER-COLOR: #565656} + +/* 3.2 Makes the top border of posts match the colour used for post headers */ + +DIV.blockpost DIV.box {BORDER-COLOR: #565656 #525252 #525252} + +/* 3.3 Table internal borders. By default TH is same as background so border is invisible */ + +.pun TD {BORDER-COLOR: #565656} +.pun TH {BORDER-COLOR: #484848} + +/* 3.4 Creates the inset border for quote boxes, code boxes and form info boxes */ + +.pun BLOCKQUOTE, DIV.codebox, DIV.forminfo, DIV.blockpost LABEL {BORDER-COLOR: #606060} + +/* 3.5 Gecko's default fieldset borders are really nasty so this gives them a colour +without interferring with IE's rather nice default */ + +.pun DIV>FIELDSET {BORDER-COLOR: #ACA899} + +/****************************************************************/ +/* 4. LINK COLOURS */ +/****************************************************************/ + +/* 4.1 This is the default for all links */ + +.pun A:link, .pun A:visited {COLOR: #60A0DC} +.pun A:hover {COLOR: #80D6FF} + +/* 4.2 This is the colour for links in header rows and the navigation bar */ + +.pun H2 A:link, .pun H2 A:visited {COLOR: #D4D4D4} +.pun H2 A:hover {COLOR: #D4D4D4} + +/* 4.3 This is for closed topics and "hot" links */ + +LI.postreport A:link, LI.postreport A:visited, TR.iclosed TD.tcl A:link, TR.iclosed TD.tcl A:visited {COLOR: #888} +LI.postreport A:hover, TR.iclosed TD.tcl A:hover {COLOR: #AAA} +LI.maintenancelink A:link, LI.maintenancelink A:visited {COLOR: #FF4000} +LI.maintenancelink A:hover {COLOR: #FF5010} + +/****************************************************************/ +/* 5. POST STATUS INDICATORS */ +/****************************************************************/ + +/* These are the post status indicators which appear at the left of some tables. +.inew = new posts, .iredirect = redirect forums, .iclosed = closed topics and +.isticky = sticky topics. The default is "icon". By default only .inew is different.*/ + +DIV.icon {BORDER-COLOR: #484848 #404040 #3C3C3C #444444} +TR.iredirect DIV.icon {BORDER-COLOR: #383838 #383838 #383838 #383838} +DIV.inew {BORDER-COLOR: #5496D8 #4B85C0 #4377AC #4F8DCB} \ No newline at end of file diff -r 000000000000 -r f9ffdbd96607 punbb/style/imports/Lithium_cs.css --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/punbb/style/imports/Lithium_cs.css Wed Jul 11 21:01:48 2007 -0400 @@ -0,0 +1,111 @@ +/****************************************************************/ +/* 1. BACKGROUND AND TEXT COLOURS */ +/****************************************************************/ + +/* 1.1 Default background colour and text colour */ + +BODY {BACKGROUND-COLOR: #FFF} + +.pun {COLOR: #333} + +DIV.box, .pun BLOCKQUOTE, DIV.codebox, #adminconsole FIELDSET TH, .rowodd, .roweven {BACKGROUND-COLOR: #F1F1F1} +#adminconsole TD, #adminconsole TH {BORDER-COLOR: #F1F1F1} + +/* 1. 2 Darker background colours */ + +TD.tc2, TD.tc3, TD.tcmod, #postpreview, #viewprofile DD, DIV.forminfo, +#adminconsole FIELDSET TD, DIV.blockmenu DIV.box, #adstats DD {BACKGROUND-COLOR: #DEDFDF} + +/* 1.3 Main headers and navigation bar background and text colour */ + +.pun H2, #brdmenu {BACKGROUND-COLOR: #6C8A3F; COLOR: #FFF} + +/* 1.4 Table header rows */ + +.pun TH, .bgc4 {BACKGROUND-COLOR: #D1D1D1} + +/* 1.5 Fieldset legend text colour */ + +.pun LEGEND {COLOR: #6C8A3F} + +/* 1.6 Highlighted text for various items */ + +.pun DIV.blockmenu LI.isactive A, #posterror LI STRONG {COLOR: #333} + +/****************************************************************/ +/* 2. POST BACKGROUNDS AND TEXT */ +/****************************************************************/ + +/* 2.1 This is the setup for posts. */ + +DIV.blockpost DIV.box, DIV.postright, DIV.postfootright {BACKGROUND-COLOR: #DEDFDF} +DIV.postright, DIV.postfootright {BORDER-LEFT-COLOR: #F1F1F1} +DIV.postleft, DIV.postfootleft, DIV.blockpost LABEL {BACKGROUND-COLOR: #F1F1F1} + +/* 2.2 Background for post headers and text colour for post numbers in viewtopic */ + +DIV.blockpost H2 {BACKGROUND-COLOR: #7EA34B} +DIV.blockpost H2 SPAN.conr {COLOR: #B7D094} + +/* 2.3 This is the line above the signature in posts. Colour and background should be the same */ + +.pun HR {BACKGROUND-COLOR: #333; COLOR: #333} + +/****************************************************************/ +/* 3. BORDER COLOURS */ +/****************************************************************/ + +/* 3.1 All external borders */ + +DIV.box {BORDER-COLOR: #6C8A3F} + +/* 3.2 Makes the top border of posts match the colour used for post headers */ + +DIV.blockpost DIV.box {BORDER-COLOR: #7EA34B #6C8A3F #6C8A3F} + +/* 3.3 Table internal borders. By default TH is same as background so border is invisible */ + +.pun TD {BORDER-COLOR: #CEDEB9} +.pun TH {BORDER-COLOR: #D1D1D1} + +/* 3.4 Creates the inset border for quote boxes, code boxes and form info boxes */ + +.pun BLOCKQUOTE, DIV.codebox, DIV.forminfo, DIV.blockpost LABEL {BORDER-COLOR: #ACA899 #FFF #FFF #ACA899} + +/* 3.5 Gecko's default fieldset borders are really nasty so this gives them a colour +without interferring with IE's rather nice default */ + +.pun DIV>FIELDSET {BORDER-COLOR: #ACA899} + +/****************************************************************/ +/* 4. LINK COLOURS */ +/****************************************************************/ + +/* 4.1 This is the default for all links */ + +.pun A:link, .pun A:visited {COLOR: #638137} +.pun A:hover {COLOR: #8EB653} + +/* 4.2 This is the colour for links in header rows and the navigation bar */ + +.pun H2 A:link, .pun H2 A:visited, #brdmenu A:link, #brdmenu A:visited {COLOR: #FFF} +.pun H2 A:hover, #brdmenu A:hover {COLOR: #FFF} + +/* 4.3 This is for closed topics and "hot" links */ + +LI.postreport A:link, LI.postreport A:visited, TR.iclosed TD.tcl A:link, TR.iclosed TD.tcl A:visited {COLOR: #888} +LI.postreport A:hover, TR.iclosed TD.tcl A:hover {COLOR: #AAA} +LI.maintenancelink A:link, LI.maintenancelink A:visited {COLOR: #B42000} +LI.maintenancelink A:hover {COLOR: #B42000} + +/****************************************************************/ +/* 5. POST STATUS INDICATORS */ +/****************************************************************/ + +/* These are the post status indicators which appear at the left of some tables. +.inew = new posts, .iredirect = redirect forums, .iclosed = closed topics and +.isticky = sticky topics. The default is "icon". By default only .inew is different.*/ + +DIV.icon {BORDER-COLOR: #E6E6E6 #DEDEDE #DADADA #E2E2E2} +TR.iredirect DIV.icon {BORDER-COLOR: #F1F1F1 #F1F1F1 #F1F1F1 #F1F1F1} +DIV.inew {BORDER-COLOR: #8BB453 #7A9E48 #709142 #799C47} \ No newline at end of file diff -r 000000000000 -r f9ffdbd96607 punbb/style/imports/Mercury_cs.css --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/punbb/style/imports/Mercury_cs.css Wed Jul 11 21:01:48 2007 -0400 @@ -0,0 +1,117 @@ +/****************************************************************/ +/* 1. BACKGROUND AND TEXT COLOURS */ +/****************************************************************/ + +/* 1.1 Default background colour and text colour */ + +BODY {BACKGROUND-COLOR: #2A2A2A} + +.pun {COLOR: #D4D4D4} + +DIV.box, #adminconsole FIELDSET TH, .rowodd, .roweven {BACKGROUND-COLOR: #383838} +#adminconsole TD, #adminconsole TH {BORDER-COLOR: #383838} + +/* 1. 2 Darker background colours */ + +TD.tc2, TD.tc3, TD.tcmod, #brdfooter DIV.box {BACKGROUND-COLOR: #424242} +#adminconsole FIELDSET TD, #viewprofile DD, DIV.forminfo, DIV.blockmenu DIV.box, #adstats DD {BACKGROUND-COLOR: #484848} + +.pun BLOCKQUOTE, DIV.codebox {BACKGROUND-COLOR: #353533} + +/* 1.3 Main headers and navigation bar background and text colour */ + +.pun H2, #brdmenu {BACKGROUND-COLOR: #565656; COLOR: #D4D4D4} + +/* 1.4 Table header rows */ + +.pun TH {BACKGROUND-COLOR: #484848} + +/* 1.5 Fieldset legend text colour */ + +.pun LEGEND {COLOR: #F6B620} + +/* 1.6 Highlighted text for various items */ + +.pun DIV.blockmenu LI.isactive A, #posterror LI STRONG {COLOR: #D4D4D4} + +/* 1.7 Dark background for form elements */ + +.pun TEXTAREA, .pun INPUT, .pun SELECT {BACKGROUND-COLOR: #2A2A2A; COLOR: #D4D4D4} + +/****************************************************************/ +/* 2. POST BACKGROUNDS AND TEXT */ +/****************************************************************/ + +/* 2.1 This is the setup for posts. */ + +DIV.blockpost DIV.box, DIV.postright, DIV.postfootright, #postpreview {BACKGROUND-COLOR: #383838} +DIV.postright, DIV.postfootright {BORDER-LEFT-COLOR: #424242} +DIV.postleft, DIV.postfootleft, DIV.blockpost LABEL {BACKGROUND-COLOR: #424242} + +/* 2.2 Background for post headers and text colour for post numbers in viewtopic */ + +DIV.blockpost H2 {BACKGROUND-COLOR: #565656} +DIV.blockpost H2 SPAN.conr {COLOR: #A19E96} + +/* 2.3 This is the line above the signature in posts. Colour and background should be the same */ + +.pun HR {BACKGROUND-COLOR: #606060; COLOR: #606060} + +/****************************************************************/ +/* 3. BORDER COLOURS */ +/****************************************************************/ + +/* 3.1 All external borders (H1 is the board title) */ + +DIV.box {BORDER-COLOR: #565656} + +/* 3.2 Makes the top border of posts match the colour used for post headers */ + +DIV.blockpost DIV.box {BORDER-COLOR: #565656 #525252 #525252} + +/* 3.3 Table internal borders. By default TH is same as background so border is invisible */ + +.pun TD {BORDER-COLOR: #565656} +.pun TH {BORDER-COLOR: #484848} + +/* 3.4 Creates the inset border for quote boxes, code boxes and form info boxes */ + +.pun BLOCKQUOTE, DIV.codebox, DIV.forminfo, DIV.blockpost LABEL {BORDER-COLOR: #565656} + +/* 3.5 Gecko's default fieldset borders are really nasty so this gives them a colour +without interferring with IE's rather nice default */ + +.pun DIV>FIELDSET {BORDER-COLOR: #909090} + +/****************************************************************/ +/* 4. LINK COLOURS */ +/****************************************************************/ + +/* 4.1 This is the default for all links */ + +.pun A:link, .pun A:visited {COLOR: #F6B620} +.pun A:hover {COLOR: #FFEE40} + +/* 4.2 This is the colour for links in header rows and the navigation bar */ + +.pun H2 A:link, .pun H2 A:visited {COLOR: #D4D4D4} +.pun H2 A:hover {COLOR: #D4D4D4} + +/* 4.3 This is for closed topics and "hot" links */ + +LI.postreport A:link, LI.postreport A:visited, TR.iclosed TD.tcl A:link, TR.iclosed TD.tcl A:visited {COLOR: #888} +LI.postreport A:hover, TR.iclosed TD.tcl A:hover {COLOR: #AAA} +LI.maintenancelink A:link, LI.maintenancelink A:visited {COLOR: #FF4000} +LI.maintenancelink A:hover {COLOR: #FF5010} + +/****************************************************************/ +/* 5. POST STATUS INDICATORS */ +/****************************************************************/ + +/* These are the post status indicators which appear at the left of some tables. +.inew = new posts, .iredirect = redirect forums, .iclosed = closed topics and +.isticky = sticky topics. The default is "icon". By default only .inew is different.*/ + +DIV.icon {BORDER-COLOR: #484848 #404040 #3C3C3C #444444} +TR.iredirect DIV.icon {BORDER-COLOR: #383838 #383838 #383838 #383838} +DIV.inew {BORDER-COLOR: #F6B620 #ECAE1F #D09A1B #E1A61D} \ No newline at end of file diff -r 000000000000 -r f9ffdbd96607 punbb/style/imports/Oxygen_cs.css --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/punbb/style/imports/Oxygen_cs.css Wed Jul 11 21:01:48 2007 -0400 @@ -0,0 +1,111 @@ +/****************************************************************/ +/* 1. BACKGROUND AND TEXT COLOURS */ +/****************************************************************/ + +/* 1.1 Default background colour and text colour */ + +BODY {BACKGROUND-COLOR: #FFF} + +.pun {COLOR: #333} + +DIV.box, .pun BLOCKQUOTE, DIV.codebox, #adminconsole FIELDSET TH, .rowodd, .roweven {BACKGROUND-COLOR: #F1F1F1} +#adminconsole TD, #adminconsole TH {BORDER-COLOR: #F1F1F1} + +/* 1. 2 Darker background colours */ + +TD.tc2, TD.tc3, TD.tcmod, #postpreview, #viewprofile DD, DIV.forminfo, +#adminconsole FIELDSET TD, DIV.blockmenu DIV.box, #adstats DD {BACKGROUND-COLOR: #DEDFDF} + +/* 1.3 Main headers and navigation bar background and text colour */ + +.pun H2, #brdmenu {BACKGROUND-COLOR: #0066B9; COLOR: #FFF} + +/* 1.4 Table header rows */ + +.pun TH {BACKGROUND-COLOR: #D1D1D1} + +/* 1.5 Fieldset legend text colour */ + +.pun LEGEND {COLOR: #005CB1} + +/* 1.6 Highlighted text for various items */ + +.pun DIV.blockmenu LI.isactive A, #posterror LI STRONG {COLOR: #333} + +/****************************************************************/ +/* 2. POST BACKGROUNDS AND TEXT */ +/****************************************************************/ + +/* 2.1 This is the setup for posts. */ + +DIV.blockpost DIV.box, DIV.postright, DIV.postfootright {BACKGROUND-COLOR: #DEDFDF} +DIV.postright, DIV.postfootright {BORDER-LEFT-COLOR: #f1f1f1} +DIV.postleft, DIV.postfootleft, DIV.blockpost LABEL {BACKGROUND-COLOR: #F1F1F1} + +/* 2.2 Background for post headers and text colour for post numbers in viewtopic */ + +DIV.blockpost H2 {BACKGROUND-COLOR: #006FC9} +DIV.blockpost H2 SPAN.conr {COLOR: #AABDCD} + +/* 2.3 This is the line above the signature in posts. Colour and background should be the same */ + +.pun HR {BACKGROUND-COLOR: #333; COLOR: #333} + +/****************************************************************/ +/* 3. BORDER COLOURS */ +/****************************************************************/ + +/* 3.1 All external borders */ + +DIV.box {BORDER-COLOR: #0066B9} + +/* 3.2 Makes the top border of posts match the colour used for post headers */ + +DIV.blockpost DIV.box {BORDER-COLOR: #006fC9 #0066B9 #0066B9} + +/* 3.3 Table internal borders. By default TH is same as background so border is invisible */ + +.pun TD {BORDER-COLOR: #BBCEDE} +.pun TH {BORDER-COLOR: #D1D1D1} + +/* 3.4 Creates the inset border for quote boxes, code boxes and form info boxes */ + +.pun BLOCKQUOTE, DIV.codebox, DIV.forminfo, DIV.blockpost LABEL {BORDER-COLOR: #ACA899 #FFF #FFF #ACA899} + +/* 3.5 Gecko's default fieldset borders are really nasty so this gives them a colour +without interferring with IE's rather nice default */ + +.pun DIV>FIELDSET {BORDER-COLOR: #ACA899} + +/****************************************************************/ +/* 4. LINK COLOURS */ +/****************************************************************/ + +/* 4.1 This is the default for all links */ + +.pun A:link, .pun A:visited {COLOR: #005CB1} +.pun A:hover {COLOR: #B42000} + +/* 4.2 This is the colour for links in header rows and the navigation bar */ + +.pun H2 A:link, .pun H2 A:visited, #brdmenu A:link, #brdmenu A:visited {COLOR: #FFF} +.pun H2 A:hover, #brdmenu A:hover {COLOR: #FFF} + +/* 4.3 This is for closed topics and "hot" links */ + +LI.postreport A:link, LI.postreport A:visited, TR.iclosed TD.tcl A:link, TR.iclosed TD.tcl A:visited {COLOR: #888} +LI.postreport A:hover, TR.iclosed TD.tcl A:hover {COLOR: #AAA} +LI.maintenancelink A:link, LI.maintenancelink A:visited {COLOR: #B42000} +LI.maintenancelink A:hover {COLOR: #B42000} + +/****************************************************************/ +/* 5. POST STATUS INDICATORS */ +/****************************************************************/ + +/* These are the post status indicators which appear at the left of some tables. +.inew = new posts, .iredirect = redirect forums, .iclosed = closed topics and +.isticky = sticky topics. The default is "icon". By default only .inew is different.*/ + +DIV.icon {BORDER-COLOR: #E6E6E6 #DEDEDE #DADADA #E2E2E2} +TR.iredirect DIV.icon {BORDER-COLOR: #F1F1F1 #F1F1F1 #F1F1F1 #F1F1F1} +DIV.inew {BORDER-COLOR: #0080D7 #0065C0 #0058B3 #0072CA} \ No newline at end of file diff -r 000000000000 -r f9ffdbd96607 punbb/style/imports/Radium_cs.css --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/punbb/style/imports/Radium_cs.css Wed Jul 11 21:01:48 2007 -0400 @@ -0,0 +1,122 @@ +/****************************************************************/ +/* 1. BACKGROUND AND TEXT COLOURS */ +/****************************************************************/ + +/* 1.1 Default background colour and text colour */ + +BODY {BACKGROUND-COLOR: #2A2A2A} + +.pun {COLOR: #D4D4D4} + +DIV.box, #adminconsole FIELDSET TH, .rowodd, .roweven {BACKGROUND-COLOR: #383838} +#adminconsole TD, #adminconsole TH {BORDER-COLOR: #383838} + +/* 1. 2 Darker background colours */ + +TD.tc2, TD.tc3, TD.tcmod, #brdfooter DIV.box {BACKGROUND-COLOR: #424242} +#adminconsole FIELDSET TD, #viewprofile DD, DIV.forminfo, DIV.blockmenu DIV.box, #adstats DD {BACKGROUND-COLOR: #484848} + +.pun BLOCKQUOTE, DIV.codebox {BACKGROUND-COLOR: #353533} + +/* 1.3 Main headers and navigation bar background and text colour */ + +.pun H2, #brdmenu {BACKGROUND-COLOR: #565656; COLOR: #D4D4D4} + +/* 1.4 Table header rows */ + +.pun TH, .bgc4 {BACKGROUND-COLOR: #484848} + +/* 1.5 Fieldset legend text colour */ + +.pun LEGEND {COLOR: #60C860} + +/* 1.6 Highlighted text for various items */ + +.pun DIV.blockmenu LI.isactive A, #posterror LI STRONG {COLOR: #D4D4D4} + +/* 1.7 Dark background for form elements */ + +.pun TEXTAREA, .pun INPUT, .pun SELECT {BACKGROUND-COLOR: #2A2A2A; COLOR: #D4D4D4} + +/****************************************************************/ +/* 2. POST BACKGROUNDS AND TEXT */ +/****************************************************************/ + +/* 2.1 This is the setup for posts. */ + +DIV.blockpost DIV.box, DIV.postright, DIV.postfootright, #postpreview {BACKGROUND-COLOR: #383838} +DIV.postright, DIV.postfootright {BORDER-LEFT-COLOR: #424242} +DIV.postleft, DIV.postfootleft, DIV.blockpost LABEL {BACKGROUND-COLOR: #424242} + +/* 2.2 Background for post headers and text colour for post numbers in viewtopic */ + +DIV.blockpost H2 {BACKGROUND-COLOR: #565656} +DIV.blockpost H2 SPAN.conr {COLOR: #A19E96} + +/* 2.3 This is the line above the signature in posts. Colour and background should be the same */ + +.pun HR {BACKGROUND-COLOR: #606060; COLOR: #606060} + +/****************************************************************/ +/* 3. BORDER COLOURS */ +/****************************************************************/ + +/* 3.1 All external borders (H1 is the board title) */ + +DIV.box {BORDER-COLOR: #565656} + +/* 3.2 Makes the top border of posts match the colour used for post headers */ + +DIV.blockpost DIV.box {BORDER-COLOR: #565656 #525252 #525252} + +/* 3.3 Table internal borders. By default TH is same as background so border is invisible */ + +.pun TD {BORDER-COLOR: #565656} +.pun TH {BORDER-COLOR: #484848} + +/* 3.4 Creates the inset border for quote boxes, code boxes and form info boxes */ + +.pun BLOCKQUOTE, DIV.codebox, DIV.forminfo, DIV.blockpost LABEL {BORDER-COLOR: #606060} + +/* 3.5 Gecko's default fieldset borders are really nasty so this gives them a colour +without interferring with IE's rather nice default */ + +.pun DIV>FIELDSET {BORDER-COLOR: #ACA899} + +/****************************************************************/ +/* 4. LINK COLOURS */ +/****************************************************************/ + +/* 4.1 This is the default for all links */ + +.pun A:link, .pun A:visited {COLOR: #60C860} +.pun A:hover {COLOR: #80EE80} + +/* 4.2 This is the colour for links in header rows and the navigation bar */ + +.pun H2 A:link, .pun H2 A:visited {COLOR: #D4D4D4} +.pun H2 A:hover {COLOR: #D4D4D4} + +/* 4.3 This is for closed topics and "hot" links */ + +LI.postreport A:link, LI.postreport A:visited, TR.iclosed TD.tcl A:link, TR.iclosed TD.tcl A:visited {COLOR: #888} +LI.postreport A:hover, TR.iclosed TD.tcl A:hover {COLOR: #AAA} +LI.maintenancelink A:link, LI.maintenancelink A:visited {COLOR: #FF4000} +LI.maintenancelink A:hover {COLOR: #FF5010} + +/****************************************************************/ +/* 5. POST STATUS INDICATORS */ +/****************************************************************/ + +/* These are the post status indicators which appear at the left of some tables. +.inew = new posts, .iredirect = redirect forums, .iclosed = closed topics and +.isticky = sticky topics. The default is "icon". By default only .inew is different.*/ + +DIV.icon {BORDER-COLOR: #484848 #404040 #3C3C3C #444444} +TR.iredirect DIV.icon {BORDER-COLOR: #383838 #383838 #383838 #383838} +DIV.inew {BORDER-COLOR: #60C860 #54AF54 #499849 #59B657} + +/* 5.2 Class .tclcon is a div inside the first column of tables with post indicators. The +margin creates space for the post status indicator */ + +TD DIV.tclcon {MARGIN-LEFT: 2.3em} diff -r 000000000000 -r f9ffdbd96607 punbb/style/imports/Sulfur_cs.css --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/punbb/style/imports/Sulfur_cs.css Wed Jul 11 21:01:48 2007 -0400 @@ -0,0 +1,111 @@ +/****************************************************************/ +/* 1. BACKGROUND AND TEXT COLOURS */ +/****************************************************************/ + +/* 1.1 Default background colour and text colour */ + +BODY {BACKGROUND-COLOR: #FFF} + +.pun {COLOR: #333} + +DIV.box, .pun BLOCKQUOTE, DIV.codebox, #adminconsole FIELDSET TH, .rowodd, .roweven {BACKGROUND-COLOR: #F1F1F1} +#adminconsole TD, #adminconsole TH {BORDER-COLOR: #F1F1F1} + +/* 1. 2 Darker background colours */ + +TD.tc2, TD.tc3, TD.tcmod, #postpreview, #viewprofile DD, DIV.forminfo, +#adminconsole FIELDSET TD, DIV.blockmenu DIV.box, #adstats DD {BACKGROUND-COLOR: #DEDFDF} + +/* 1.3 Main headers and navigation bar background and text colour */ + +.pun H2, #brdmenu {BACKGROUND-COLOR: #B84623; COLOR: #FFF} + +/* 1.4 Table header rows */ + +.pun TH {BACKGROUND-COLOR: #D1D1D1} + +/* 1.5 Fieldset legend text colour */ + +.pun LEGEND {COLOR: #822100} + +/* 1.6 Highlighted text for various items */ + +.pun DIV.blockmenu LI.isactive A, #posterror LI STRONG {COLOR: #333} + +/****************************************************************/ +/* 2. POST BACKGROUNDS AND TEXT */ +/****************************************************************/ + +/* 2.1 This is the setup for posts. */ + +DIV.blockpost DIV.box, DIV.postright, DIV.postfootright {BACKGROUND-COLOR: #DEDFDF} +DIV.postright, DIV.postfootright {BORDER-LEFT-COLOR: #F1F1F1} +DIV.postleft, DIV.postfootleft, DIV.blockpost LABEL {BACKGROUND-COLOR: #F1F1F1} + +/* 2.2 Background for post headers and text colour for post numbers in viewtopic */ + +DIV.blockpost H2 {BACKGROUND-COLOR: #D25028} +DIV.blockpost H2 SPAN.conr {COLOR: #FCCFC1} + +/* 2.3 This is the line above the signature in posts. Colour and background should be the same */ + +.pun HR {BACKGROUND-COLOR: #333; COLOR: #333} + +/****************************************************************/ +/* 3. BORDER COLOURS */ +/****************************************************************/ + +/* 3.1 All external borders */ + +DIV.box {BORDER-COLOR: #B84623} + +/* 3.2 Makes the top border of posts match the colour used for post headers */ + +DIV.blockpost DIV.box {BORDER-COLOR: #D25028 #B84623 #B84623} + +/* 3.3 Table internal borders. By default TH is same as background so border is invisible */ + +.pun TD {BORDER-COLOR: #E1C3C3} +.pun TH {BORDER-COLOR: #D1D1D1} + +/* 3.4 Creates the inset border for quote boxes, code boxes and form info boxes */ + +.pun BLOCKQUOTE, DIV.codebox, DIV.forminfo, DIV.blockpost LABEL {BORDER-COLOR: #ACA899 #FFF #FFF #ACA899} + +/* 3.5 Gecko's default fieldset borders are really nasty so this gives them a colour +without interferring with IE's rather nice default */ + +.pun DIV>FIELDSET {BORDER-COLOR: #ACA899} + +/****************************************************************/ +/* 4. LINK COLOURS */ +/****************************************************************/ + +/* 4.1 This is the default for all links */ + +.pun A:link, .pun A:visited {COLOR: #822100} +.pun A:hover {COLOR: #CA3300} + +/* 4.2 This is the colour for links in header rows and the navigation bar */ + +.pun H2 A:link, .pun H2 A:visited, #brdmenu A:link, #brdmenu A:visited {COLOR: #FFF} +.pun H2 A:hover, #brdmenu A:hover {COLOR: #FFF} + +/* 4.3 This is for closed topics and "hot" links */ + +LI.postreport A:link, LI.postreport A:visited, TR.iclosed TD.tcl A:link, TR.iclosed TD.tcl A:visited {COLOR: #888} +LI.postreport A:hover, TR.iclosed TD.tcl A:hover {COLOR: #AAA} +LI.maintenancelink A:link, LI.maintenancelink A:visited {COLOR: #B42000} +LI.maintenancelink A:hover {COLOR: #B42000} + +/****************************************************************/ +/* 5. POST STATUS INDICATORS */ +/****************************************************************/ + +/* These are the post status indicators which appear at the left of some tables. +.inew = new posts, .iredirect = redirect forums, .iclosed = closed topics and +.isticky = sticky topics. The default is "icon". By default only .inew is different.*/ + +DIV.icon {BORDER-COLOR: #E6E6E6 #DEDEDE #DADADA #E2E2E2} +TR.iredirect DIV.icon {BORDER-COLOR: #F1F1F1 #F1F1F1 #F1F1F1 #F1F1F1} +DIV.inew {BORDER-COLOR: #C23000 #AF2C00 #992600 #AC2B00} \ No newline at end of file diff -r 000000000000 -r f9ffdbd96607 punbb/style/imports/base.css --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/punbb/style/imports/base.css Wed Jul 11 21:01:48 2007 -0400 @@ -0,0 +1,273 @@ +/****************************************************************/ +/* 1. INITIAL SETTINGS */ +/****************************************************************/ + +.pun TABLE, .pun DIV, .pun FORM, .pun P, .pun H1, .pun H2, .pun H3, +.pun H4, .pun PRE, .pun BLOCKQUOTE, .pun UL, .pun OL, .pun LI, .pun DL, +.pun DT, .pun DD, .pun TH, .pun TD, .pun FIELDSET, .pun IMG { + MARGIN: 0px; + PADDING: 0px; + FONT-WEIGHT: normal; + LIST-STYLE: none; +} + +.pun IMG {BORDER: none} + +.pun INPUT, .pun SELECT, .pun TEXTAREA, .pun OPTGROUP {MARGIN: 0} + +/****************************************************************/ +/* 2. STRUCTURAL SETTINGS - VERY IMPORTANT - DO NOT CHANGE */ +/****************************************************************/ + +/* 2.1 Clearing floats and invisible items */ +.pun .clearer, .pun .nosize { + HEIGHT: 0; + WIDTH: 0; + LINE-HEIGHT: 0; + FONT-SIZE: 0; + OVERFLOW: hidden +} + +.pun .clearer, .pun .clearb {CLEAR: both} +.pun .nosize {POSITION: absolute; LEFT: -10000px} + +/* 2.2 Overflow settings for posts */ + +DIV.blockpost DIV.box, DIV.postleft, DIV.postsignature, DIV.postmsg {OVERFLOW: hidden} + +/****************************************************************/ +/* 3. BUG FIXES - VERY IMPORTANT - DO NOT CHANGE */ +/****************************************************************/ + +/* 3.1 This attempts to eliminate rounding errors in Gecko browsers. */ + +DIV>DIV>DIV.postfootleft, DIV>DIV>DIV.postfootright {PADDING-TOP: 1px; MARGIN-TOP: -1px} + +/* 3.2 This is only visible to IE6 Windows and cures various bugs. Do not alter comments */ + +/* Begin IE6Win Fix \*/ +* HTML .inbox, * HTML .inform, * HTML .pun, * HTML .intd, * HTML .tclcon {HEIGHT: 1px} +* HTML .inbox DIV.postmsg {WIDTH: 98%} +/* End of IE6Win Fix */ + +/* 3.3 This is the equivelant of 3.2 but for IE7. It is visible to other browsers +but does no harm */ + +/*Begin IE7Win Fix */ +.pun, .pun .inbox, .pun .inform, .pun .intd, .pun .tclcon {min-height: 1px} +/* End of IE7Win Fix */ + +/****************************************************************/ +/* 4. HIDDEN ELEMENTS */ +/****************************************************************/ + +/* These are hidden in normal display. Add comments to make them visible */ + +#brdfooter H2, #brdstats H2, #brdstats .conl DT, #brdstats .conr DT, +#modcontrols DT, #searchlinks DT, DIV.postright H3 { + POSITION: absolute; + DISPLAY: block; + OVERFLOW: hidden; + WIDTH: 1em; + LEFT: -999em +} + +/****************************************************************/ +/* 5. BOX CONTAINERS AND FLOATS */ +/****************************************************************/ + +/* 5.1. Setup all left and right content using floats. */ + +.conr { + FLOAT: right; + TEXT-ALIGN: right; + CLEAR: right; + WIDTH: 40% +} + +.conl { + FLOAT: left; + WIDTH: 55%; + OVERFLOW: hidden; + WHITE-SPACE: nowrap +} + +LABEL.conl { + WIDTH: auto; + OVERFLOW: visible; + MARGIN-RIGHT: 10px +} + +/* 5.2 Set up page numbering and posts links */ + +DIV.linkst .conl, DIV.linksb .conl, DIV.postlinksb .conl {WIDTH:18em} + +DIV.linkst .conr, DIV.linksb .conr, DIV.postlinksb .conr {WIDTH:16em} + +FORM DIV.linksb .conr {WIDTH: 32em} + +/* 5.3 Keep breadcrumbs from shifting to the right when wrapping */ + +.linkst UL, linksb UL, .postlinksb UL {MARGIN-LEFT: 18em} + +/* 5.4 Settings for Profile and Admin interface.*/ + +DIV.block2col {PADDING-BOTTOM: 1px} + +DIV.block2col DIV.blockform, DIV.block2col DIV.block, #viewprofile DD {MARGIN-LEFT: 14em} + +DIV.blockmenu, #viewprofile DT { + FLOAT:left; + WIDTH: 13em +} + +#profileavatar IMG { + FLOAT: right; + MARGIN-LEFT: 1em +} + +#viewprofile DL {FLOAT: left; WIDTH: 100%; OVERFLOW: hidden} + +/****************************************************************/ +/* 6. TABLE SETUP */ +/****************************************************************/ + +/* 6.1 Table Basic Setup */ + +.pun TABLE {WIDTH: 100%} + +/* 6.2 Fixed Table Setup */ + +#punindex TABLE, #vf TABLE {TABLE-LAYOUT: fixed} + +.tcl {TEXT-ALIGN: left; WIDTH: 50%} + +.tc2, .tc3, .tcmod {WIDTH: 9%; TEXT-ALIGN: center} + +.tcr {WIDTH: 32%; TEXT-ALIGN: left} + +#punsearch #vf .tcl, #punmoderate #vf .tcl {WIDTH: 41%} + +#punsearch #vf .tc2 {WIDTH: 18%; TEXT-ALIGN: left} + +.tcl, .tcr {OVERFLOW: HIDDEN} + +/* 6.3 Other Table Setup */ + +#users1 .tcl {WIDTH: 40%} + +#users1 .tcr {WIDTH: 25%} + +#users1 .tc2 {WIDTH: 25%; TEXT-ALIGN: left} + +#users1 .tc3 {WIDTH: 10%; TEXT-ALIGN: center} + +#debug .tcr {WIDTH: 85%; WHITE-SPACE: normal} + +#punindex TD.tcr SPAN.byuser {DISPLAY: block} + +/****************************************************************/ +/* 7. VIEWTOPIC SETUP */ +/****************************************************************/ + +/* 7.1 This is the basic structure. */ + +DIV.postleft, DIV.postfootleft { + FLOAT:left; + WIDTH: 18em; + OVERFLOW: hidden; + POSITION: relative; +} + +DIV.postright, DIV.postfootright { + BORDER-LEFT-WIDTH: 18em; + BORDER-LEFT-STYLE: solid +} + +DIV.postfootright, P.multidelete {TEXT-ALIGN: right} + +DIV.blockpost>DIV>DIV.inbox {PADDING-BOTTOM: 1px} + +/* 7.3 This is the div which actually contains the post and is inside .postright */ + +DIV.postmsg {WIDTH:100%} + +/* 7.4 These items control overflow and scrolling within posts. */ + +DIV.incqbox {WIDTH: 100%; OVERFLOW: hidden} +DIV.scrollbox {WIDTH: 100%; OVERFLOW: auto} +IMG.postimg {max-width: 100%} +A .postimg {max-width: 100%} + +/* 7.5 Turn off the poster information column for preview */ + +#postpreview DIV.postright {BORDER-LEFT: none} + +/* 7.6 Create the horizontal line above signatures */ + +DIV.postsignature HR { + MARGIN-LEFT: 0px; + WIDTH: 200px; + TEXT-ALIGN: left; + HEIGHT: 1px; + BORDER:none +} + +/* 7.7 Maximum height for search results as posts. Position go to post link */ + +DIV.searchposts DIV.postmsg {HEIGHT: 8em} +DIV.searchposts DD P {PADDING-TOP: 3em} + +/* 7.8 Class for bbcode [u] */ + +SPAN.bbu {TEXT-DECORATION: underline} + +/****************************************************************/ +/* 8. LISTS SPECIAL SETTINGS */ +/****************************************************************/ + +/* 8.1 Horizontal display of online list, main navigation menu and breadcrumbs */ + +#onlinelist DD, #onlinelist DT, #brdmenu LI, DIV.linkst LI, DIV.linksb LI, DIV.postlinksb LI, +DIV.postfootright LI, UL.bblinks LI { + DISPLAY: inline; + HEIGHT: 0 +} + +/* 8.2 Turn on square icon for posterror list */ + +#posterror UL LI {LIST-STYLE: square inside} + +/* 8.3 Right alignment of descriptions in ordinary member view of other members profiles */ + +#viewprofile DT {TEXT-ALIGN: right} + +/****************************************************************/ +/* 9. FORM SETTINGS */ +/****************************************************************/ + +/* 9.1 Makes textareas and long text inputs shrink with page */ + +DIV.txtarea {WIDTH: 75%} + +DIV.txtarea TEXTAREA, INPUT.longinput {WIDTH: 100%} + +.pun LABEL {DISPLAY: block} + +#qjump SELECT {WIDTH: 50%} + +/****************************************************************/ +/* 10. HELP FILES AND MISC. */ +/****************************************************************/ + +/* 10.1 Put some space between sections of the help file */ + +#helpfile H2 {MARGIN-TOP: 12px} + +/* 10.2 Internal padding */ + +#helpfile DIV.box {PADDING: 10px} + +/* 10.3 Other templates */ + +#punredirect DIV.block, #punmaint DIV.block {MARGIN: 50px 20% 12px 20%} diff -r 000000000000 -r f9ffdbd96607 punbb/style/imports/base_admin.css --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/punbb/style/imports/base_admin.css Wed Jul 11 21:01:48 2007 -0400 @@ -0,0 +1,45 @@ +#adminconsole .block2 {MARGIN-TOP: 12px} + +/*** Admin Main Content ***/ +* HTML #adstats DD {HEIGHT: 1%} +#adstats DD {MARGIN-LEFT: 14em; PADDING: 3px; MARGIN-BOTTOM: 5px; LINE-HEIGHT: 1.5em} +#adstats DT {FLOAT:left; WIDTH: 13em; PADDING: 3px; line-height: 1.5em} +#adstats {PADDING: 15px 15px 5px 10px} +#adintro {PADDING: 5px} +#adintro P {PADDING: 10px} +#adstats DL {PADDING: 5px 0 10px 5px} + +#adminconsole FIELDSET TD {TEXT-ALIGN: left; PADDING: 4px; WHITE-SPACE: normal} +#adminconsole FIELDSET TH {TEXT-ALIGN: left; PADDING: 4px; WHITE-SPACE: normal} +#adminconsole FIELDSET TD SPAN, #adminconsole FIELDSET TH SPAN {DISPLAY: block; FONT-SIZE: 1em; FONT-WEIGHT: normal} +#adminconsole TH {WIDTH: 15em; FONT-WEIGHT: bold} +#adminconsole INPUT, #adminconsole SELECT, #adminconsole TEXTAREA {MARGIN-BOTTOM: 0; MARGIN-TOP: 0; FONT-WEIGHT: normal} +#adminconsole TABLE.aligntop TH, #adminconsole TABLE.aligntop TD {VERTICAL-ALIGN: top} +#adminconsole TABLE.aligntop TH {PADDING-TOP: 0.7em} +#adminconsole TD, #adminconsole TH {BORDER-STYLE: solid; BORDER-WIDTH: 3px 0px 3px 0px} +#adminconsole P {PADDING-BOTTOM: 6px} +#adminconsole .topspace {PADDING-TOP: 6px} +#adminconsole P.submittop, #adminconsole P.submitend {TEXT-ALIGN: center} +#adminconsole TH.hidehead {COLOR: #f1f1f1} +#adminconsole THEAD TH {PADDING-BOTTOM: 0px} +#adminconsole P.linkactions {FONT-WEIGHT: bold; PADDING-LEFT: 5px} +#adminconsole TH INPUT, #adminconsole DIV.fsetsubmit {MARGIN-TOP: 6px} + +/*** Particular table settings ***/ +#categoryedit .tcl {WIDTH: 25%} +#censoring .tcl, #censoring .tc2, #ranks .tcl, #ranks .tc2 {WIDTH: 20%} +TABLE#forumperms TH, TABLE#forumperms TD {WHITE-SPACE: normal; WIDTH: auto; TEXT-ALIGN: center} +TABLE#forumperms .atcl {TEXT-ALIGN: left; WIDTH: 15em; WHITE-SPACE: nowrap} +#adminconsole TD.nodefault {BACKGROUND-COLOR: #D59B9B} + +/*** User Search Result Tables ***/ +#users2 TH, #users2 TH {TEXT-ALIGN: left} +#users2 .tcl, #users2 .tc3, #users2 .tc5 {WIDTH: 15%; TEXT-ALIGN: left} +#users2 .tc2 {WIDTH: 22%; TEXT-ALIGN: left} +#users2 .tc4 {WIDTH: 8%} +#users2 .tc4 {TEXT-ALIGN: center} +#users2 .tcr {WHITE-SPACE: nowrap} +#adminconsole #linkst, #adminconsole #linksb A {FONT-WEIGHT: bold} + +/*** Plugins ***/ +#exampleplugin .inbox {PADDING: 6px 6px 0px 6px} diff -r 000000000000 -r f9ffdbd96607 punbb/style/imports/index.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/punbb/style/imports/index.html Wed Jul 11 21:01:48 2007 -0400 @@ -0,0 +1,8 @@ + + +. + + +. + + \ No newline at end of file diff -r 000000000000 -r f9ffdbd96607 punbb/style/imports/minmax.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/punbb/style/imports/minmax.js Wed Jul 11 21:01:48 2007 -0400 @@ -0,0 +1,84 @@ +// minmax.js - written by Andrew Clover +// Adapted for PunBB by Rickard Andersson and Paul Sullivan + +/*@cc_on +@if (@_win32 && @_jscript_version>4) + +var minmax_elements; + +function minmax_bind(el) { + var em, ms; + var st= el.style, cs= el.currentStyle; + + if (minmax_elements==window.undefined) { + if (!document.body || !document.body.currentStyle) return; + minmax_elements= new Array(); + window.attachEvent('onresize', minmax_delayout); + } + + if (cs['max-width']) + st['maxWidth']= cs['max-width']; + + ms= cs['maxWidth']; + if (ms && ms!='auto' && ms!='none' && ms!='0' && ms!='') { + st.minmaxWidth= cs.width; + minmax_elements[minmax_elements.length]= el; + minmax_delayout(); + } +} + +var minmax_delaying= false; +function minmax_delayout() { + if (minmax_delaying) return; + minmax_delaying= true; + window.setTimeout(minmax_layout, 0); +} + +function minmax_stopdelaying() { + minmax_delaying= false; +} + +function minmax_layout() { + window.setTimeout(minmax_stopdelaying, 100); + var i, el, st, cs, optimal, inrange; + for (i= minmax_elements.length; i-->0;) { + el= minmax_elements[i]; st= el.style; cs= el.currentStyle; + + st.width= st.minmaxWidth; optimal= el.offsetWidth; + inrange= true; + if (inrange && cs.minWidth && cs.minWidth!='0' && cs.minWidth!='auto' && cs.minWidth!='') { + st.width= cs.minWidth; + inrange= (el.offsetWidthoptimal); + } + if (inrange) st.width= st.minmaxWidth; + } +} + +var minmax_SCANDELAY= 500; + +function minmax_scan() { + var el; + for (var i= 0; i + +. + + +. + + \ No newline at end of file diff -r 000000000000 -r f9ffdbd96607 punbb/userlist.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/punbb/userlist.php Wed Jul 11 21:01:48 2007 -0400 @@ -0,0 +1,193 @@ + 2) ? -1 : intval($_GET['show_group']); +$sort_by = (!isset($_GET['sort_by']) || $_GET['sort_by'] != 'username' && $_GET['sort_by'] != 'registered' && ($_GET['sort_by'] != 'num_posts' || !$show_post_count)) ? 'username' : $_GET['sort_by']; +$sort_dir = (!isset($_GET['sort_dir']) || $_GET['sort_dir'] != 'ASC' && $_GET['sort_dir'] != 'DESC') ? 'ASC' : strtoupper($_GET['sort_dir']); + + +$page_title = pun_htmlspecialchars($pun_config['o_board_title']).' / '.$lang_common['User list']; +if ($pun_user['g_search_users'] == '1') + $focus_element = array('userlist', 'username'); + +define('PUN_ALLOW_INDEX', 1); +require PUN_ROOT.'header.php'; + +?> +
    +

    +
    +
    +
    +
    + +
    + + + + +

    +
    +
    +
    +

    +
    +
    +
    +escape(str_replace('*', '%', $username)).'\''; +if ($show_group > -1) + $where_sql[] = 'u.group_id='.$show_group; + +// Fetch user count +$result = $db->query('SELECT COUNT(id) FROM '.$db->prefix.'users AS u WHERE u.id>1'.(!empty($where_sql) ? ' AND '.implode(' AND ', $where_sql) : '')) or error('Unable to fetch user list count', __FILE__, __LINE__, $db->error()); +$num_users = $db->result($result); + + +// Determine the user offset (based on $_GET['p']) +$num_pages = ceil($num_users / 50); + +$p = (!isset($_GET['p']) || $_GET['p'] <= 1 || $_GET['p'] > $num_pages) ? 1 : $_GET['p']; +$start_from = 50 * ($p - 1); + +// Generate paging links +$paging_links = $lang_common['Pages'].': '.paginate($num_pages, $p, 'userlist.php?username='.urlencode($username).'&show_group='.$show_group.'&sort_by='.$sort_by.'&sort_dir='.strtoupper($sort_dir)); + + +?> +
    +
    + +
    +
    + +
    +

    +
    +
    + + + + + + + + + + +query('SELECT u.id, u.username, u.title, u.num_posts, u.registered, g.g_id, g.g_user_title FROM '.$db->prefix.'users AS u LEFT JOIN '.$db->prefix.'groups AS g ON g.g_id=u.group_id WHERE u.id>1'.(!empty($where_sql) ? ' AND '.implode(' AND ', $where_sql) : '').' ORDER BY '.$sort_by.' '.$sort_dir.' LIMIT '.$start_from.', 50') or error('Unable to fetch user list', __FILE__, __LINE__, $db->error()); +if ($db->num_rows($result)) +{ + while ($user_data = $db->fetch_assoc($result)) + { + $user_title_field = get_title($user_data); + +?> + + + + + + + +'."\n\t\t\t\t\t".''."\n"; + +?> + +
    '.pun_htmlspecialchars($user_data['username']).'' ?>
    '.$lang_search['No hits'].'
    +
    +
    +
    + +
    +
    + +
    +
    +query('SELECT f.forum_name, f.redirect_url, f.moderators, f.num_topics, f.sort_by, fp.post_topics FROM '.$db->prefix.'forums AS f LEFT JOIN '.$db->prefix.'forum_perms AS fp ON (fp.forum_id=f.id AND fp.group_id='.$pun_user['g_id'].') WHERE (fp.read_forum IS NULL OR fp.read_forum=1) AND f.id='.$id) or error('Unable to fetch forum info', __FILE__, __LINE__, $db->error()); +if (!$db->num_rows($result)) + message($lang_common['Bad request']); + +$cur_forum = $db->fetch_assoc($result); + +// Is this a redirect forum? In that case, redirect! +if ($cur_forum['redirect_url'] != '') +{ + header('Location: '.$cur_forum['redirect_url']); + exit; +} + +// Sort out who the moderators are and if we are currently a moderator (or an admin) +$mods_array = array(); +if ($cur_forum['moderators'] != '') + $mods_array = unserialize($cur_forum['moderators']); + +$is_admmod = ($pun_user['g_id'] == PUN_ADMIN || ($pun_user['g_id'] == PUN_MOD && array_key_exists($pun_user['username'], $mods_array))) ? true : false; + +// Can we or can we not post new topics? +if (($cur_forum['post_topics'] == '' && $pun_user['g_post_topics'] == '1') || $cur_forum['post_topics'] == '1' || $is_admmod) + $post_link = "\t\t".''."\n"; +else + $post_link = ''; + + +// Determine the topic offset (based on $_GET['p']) +$num_pages = ceil($cur_forum['num_topics'] / $pun_user['disp_topics']); + +$p = (!isset($_GET['p']) || $_GET['p'] <= 1 || $_GET['p'] > $num_pages) ? 1 : $_GET['p']; +$start_from = $pun_user['disp_topics'] * ($p - 1); + +// Generate paging links +$paging_links = $lang_common['Pages'].': '.paginate($num_pages, $p, 'viewforum.php?id='.$id); + + +$page_title = pun_htmlspecialchars($pun_config['o_board_title'].' / '.$cur_forum['forum_name']); +define('PUN_ALLOW_INDEX', 1); +require PUN_ROOT.'header.php'; + +?> +
    +
    + + +
    •  
    • » 
    +
    +
    +
    + +
    +

    +
    +
    + + + + + + + + + + +prefix.'topics WHERE forum_id='.$id.' ORDER BY sticky DESC, '.(($cur_forum['sort_by'] == '1') ? 'posted' : 'last_post').' DESC LIMIT '.$start_from.', '.$pun_user['disp_topics']; +} +else +{ + // With "the dot" + switch ($db_type) + { + case 'mysql': + case 'mysqli': + $sql = 'SELECT p.poster_id AS has_posted, t.id, t.subject, t.poster, 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='.$pun_user['id'].' WHERE t.forum_id='.$id.' GROUP BY t.id ORDER BY sticky DESC, '.(($cur_forum['sort_by'] == '1') ? 'posted' : 'last_post').' DESC LIMIT '.$start_from.', '.$pun_user['disp_topics']; + break; + + case 'sqlite': + $sql = 'SELECT p.poster_id AS has_posted, t.id, t.subject, t.poster, 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='.$pun_user['id'].' WHERE t.id IN(SELECT id FROM '.$db->prefix.'topics WHERE forum_id='.$id.' ORDER BY sticky DESC, '.(($cur_forum['sort_by'] == '1') ? 'posted' : 'last_post').' DESC LIMIT '.$start_from.', '.$pun_user['disp_topics'].') GROUP BY t.id ORDER BY t.sticky DESC, t.last_post DESC'; + break; + + default: + $sql = 'SELECT p.poster_id AS has_posted, t.id, t.subject, t.poster, 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='.$pun_user['id'].' WHERE t.forum_id='.$id.' GROUP BY t.id, t.subject, t.poster, 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, p.poster_id ORDER BY sticky DESC, '.(($cur_forum['sort_by'] == '1') ? 'posted' : 'last_post').' DESC LIMIT '.$start_from.', '.$pun_user['disp_topics']; + break; + + } +} + +$result = $db->query($sql) or error('Unable to fetch topic list', __FILE__, __LINE__, $db->error()); + +// If there are topics in this forum. +if ($db->num_rows($result)) +{ + while ($cur_topic = $db->fetch_assoc($result)) + { + $icon_text = $lang_common['Normal icon']; + $item_status = ''; + $icon_type = 'icon'; + + if ($cur_topic['moved_to'] == null) + $last_post = ''.format_time($cur_topic['last_post']).''.$lang_common['by'].' '.pun_htmlspecialchars($cur_topic['last_poster']).''; + else + $last_post = ' '; + + if ($pun_config['o_censoring'] == '1') + $cur_topic['subject'] = censor_words($cur_topic['subject']); + + if ($cur_topic['moved_to'] != 0) + $subject = $lang_forum['Moved'].': '.pun_htmlspecialchars($cur_topic['subject']).''.$lang_common['by'].' '.pun_htmlspecialchars($cur_topic['poster']).''; + else if ($cur_topic['closed'] == '0') + $subject = ''.pun_htmlspecialchars($cur_topic['subject']).''.$lang_common['by'].' '.pun_htmlspecialchars($cur_topic['poster']).''; + else + { + $subject = ''.pun_htmlspecialchars($cur_topic['subject']).''.$lang_common['by'].' '.pun_htmlspecialchars($cur_topic['poster']).''; + $icon_text = $lang_common['Closed icon']; + $item_status = 'iclosed'; + } + + if (!$pun_user['is_guest'] && $cur_topic['last_post'] > $pun_user['last_visit'] && $cur_topic['moved_to'] == null) + { + $icon_text .= ' '.$lang_common['New icon']; + $item_status .= ' inew'; + $icon_type = 'icon inew'; + $subject = ''.$subject.''; + $subject_new_posts = ''.$lang_common['New posts'].' ]'; + } + else + $subject_new_posts = null; + + // Should we display the dot or not? :) + if (!$pun_user['is_guest'] && $pun_config['o_show_dot'] == '1') + { + if ($cur_topic['has_posted'] == $pun_user['id']) + $subject = '· '.$subject; + else + $subject = '  '.$subject; + } + + if ($cur_topic['sticky'] == '1') + { + $subject = ''.$lang_forum['Sticky'].': '.$subject; + $item_status .= ' isticky'; + $icon_text .= ' '.$lang_forum['Sticky']; + } + + $num_pages_topic = ceil(($cur_topic['num_replies'] + 1) / $pun_user['disp_posts']); + + if ($num_pages_topic > 1) + $subject_multipage = '[ '.paginate($num_pages_topic, -1, 'viewtopic.php?id='.$cur_topic['id']).' ]'; + else + $subject_multipage = null; + + // Should we show the "New posts" and/or the multipage links? + if (!empty($subject_new_posts) || !empty($subject_multipage)) + { + $subject .= '  '.(!empty($subject_new_posts) ? $subject_new_posts : ''); + $subject .= !empty($subject_multipage) ? ' '.$subject_multipage : ''; + } + +?> + > + + + + + + + + + + + +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    + +
    +
    + + +
    •  
    • » 
    +
    +
    +
    +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); + + // Determine on what page the post is located (depending on $pun_user['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) + { + $cur_id = $db->result($result, $i); + if ($cur_id == $pid) + break; + } + ++$i; // we started at 0 + + $_GET['p'] = ceil($i / $pun_user['disp_posts']); +} + +// If action=new, we redirect to the first new post (if any) +else if ($action == 'new' && !$pun_user['is_guest']) +{ + $result = $db->query('SELECT MIN(id) FROM '.$db->prefix.'posts WHERE topic_id='.$id.' AND posted>'.$pun_user['last_visit']) or error('Unable to fetch post info', __FILE__, __LINE__, $db->error()); + $first_new_post_id = $db->result($result); + + if ($first_new_post_id) + header('Location: viewtopic.php?pid='.$first_new_post_id.'#p'.$first_new_post_id); + else // If there is no new post, we go to the last post + header('Location: viewtopic.php?id='.$id.'&action=last'); + + exit; +} + +// If action=last, we redirect to the last post +else if ($action == 'last') +{ + $result = $db->query('SELECT MAX(id) FROM '.$db->prefix.'posts WHERE topic_id='.$id) or error('Unable to fetch post info', __FILE__, __LINE__, $db->error()); + $last_post_id = $db->result($result); + + if ($last_post_id) + { + header('Location: viewtopic.php?pid='.$last_post_id.'#p'.$last_post_id); + exit; + } +} + + +// Fetch some info about the topic +if (!$pun_user['is_guest']) + $result = $db->query('SELECT t.subject, t.closed, t.num_replies, t.sticky, f.id AS forum_id, f.forum_name, f.moderators, fp.post_replies, s.user_id AS is_subscribed FROM '.$db->prefix.'topics AS t INNER JOIN '.$db->prefix.'forums AS f ON f.id=t.forum_id LEFT JOIN '.$db->prefix.'subscriptions AS s ON (t.id=s.topic_id AND s.user_id='.$pun_user['id'].') LEFT JOIN '.$db->prefix.'forum_perms AS fp ON (fp.forum_id=f.id AND fp.group_id='.$pun_user['g_id'].') WHERE (fp.read_forum IS NULL OR fp.read_forum=1) AND t.id='.$id.' AND t.moved_to IS NULL') or error('Unable to fetch topic info', __FILE__, __LINE__, $db->error()); +else + $result = $db->query('SELECT t.subject, t.closed, t.num_replies, t.sticky, f.id AS forum_id, f.forum_name, f.moderators, fp.post_replies, 0 FROM '.$db->prefix.'topics AS t INNER JOIN '.$db->prefix.'forums AS f ON f.id=t.forum_id LEFT JOIN '.$db->prefix.'forum_perms AS fp ON (fp.forum_id=f.id AND fp.group_id='.$pun_user['g_id'].') WHERE (fp.read_forum IS NULL OR fp.read_forum=1) AND t.id='.$id.' AND t.moved_to IS NULL') or error('Unable to fetch topic info', __FILE__, __LINE__, $db->error()); + +if (!$db->num_rows($result)) + message($lang_common['Bad request']); + +$cur_topic = $db->fetch_assoc($result); + +// Sort out who the moderators are and if we are currently a moderator (or an admin) +$mods_array = ($cur_topic['moderators'] != '') ? unserialize($cur_topic['moderators']) : array(); +$is_admmod = ($pun_user['g_id'] == PUN_ADMIN || ($pun_user['g_id'] == PUN_MOD && array_key_exists($pun_user['username'], $mods_array))) ? true : false; + +// Can we or can we not post replies? +if ($cur_topic['closed'] == '0') +{ + if (($cur_topic['post_replies'] == '' && $pun_user['g_post_replies'] == '1') || $cur_topic['post_replies'] == '1' || $is_admmod) + $post_link = ''.$lang_topic['Post reply'].''; + else + $post_link = ' '; +} +else +{ + $post_link = $lang_topic['Topic closed']; + + if ($is_admmod) + $post_link .= ' / '.$lang_topic['Post reply'].''; +} + + +// Determine the post offset (based on $_GET['p']) +$num_pages = ceil(($cur_topic['num_replies'] + 1) / $pun_user['disp_posts']); + +$p = (!isset($_GET['p']) || $_GET['p'] <= 1 || $_GET['p'] > $num_pages) ? 1 : $_GET['p']; +$start_from = $pun_user['disp_posts'] * ($p - 1); + +// Generate paging links +$paging_links = $lang_common['Pages'].': '.paginate($num_pages, $p, 'viewtopic.php?id='.$id); + + +if ($pun_config['o_censoring'] == '1') + $cur_topic['subject'] = censor_words($cur_topic['subject']); + + +$quickpost = false; +if ($pun_config['o_quickpost'] == '1' && + !$pun_user['is_guest'] && + ($cur_topic['post_replies'] == '1' || ($cur_topic['post_replies'] == '' && $pun_user['g_post_replies'] == '1')) && + ($cur_topic['closed'] == '0' || $is_admmod)) +{ + $required_fields = array('req_message' => $lang_common['Message']); + $quickpost = true; +} + +if (!$pun_user['is_guest'] && $pun_config['o_subscriptions'] == '1') +{ + if ($cur_topic['is_subscribed']) + // I apologize for the variable naming here. It's a mix of subscription and action I guess :-) + $subscraction = ''."\n"; + else + $subscraction = ''."\n"; +} +else + $subscraction = '
    '."\n"; + +$page_title = pun_htmlspecialchars($pun_config['o_board_title'].' / '.$cur_topic['subject']); +define('PUN_ALLOW_INDEX', 1); +require PUN_ROOT.'header.php'; + +?> +
    +
    + + +
    •  » 
    •  » 
    +
    +
    +
    + +query('SELECT u.email, u.title, u.url, u.location, u.use_avatar, u.signature, u.email_setting, u.num_posts, u.registered, u.admin_note, p.id, p.poster AS username, p.poster_id, p.poster_ip, p.poster_email, p.message, p.hide_smilies, p.posted, p.edited, p.edited_by, g.g_id, g.g_user_title, o.user_id AS is_online FROM '.$db->prefix.'posts AS p INNER JOIN '.$db->prefix.'users AS u ON u.id=p.poster_id INNER JOIN '.$db->prefix.'groups AS g ON g.g_id=u.group_id LEFT JOIN '.$db->prefix.'online AS o ON (o.user_id=u.id AND o.user_id!=1 AND o.idle=0) WHERE p.topic_id='.$id.' ORDER BY p.id LIMIT '.$start_from.','.$pun_user['disp_posts'], true) or error('Unable to fetch post info', __FILE__, __LINE__, $db->error()); +while ($cur_post = $db->fetch_assoc($result)) +{ + $post_count++; + $user_avatar = ''; + $user_info = array(); + $user_contacts = array(); + $post_actions = array(); + $is_online = ''; + $signature = ''; + + // If the poster is a registered user. + if ($cur_post['poster_id'] > 1) + { + $username = ''.pun_htmlspecialchars($cur_post['username']).''; + $user_title = get_title($cur_post); + + if ($pun_config['o_censoring'] == '1') + $user_title = censor_words($user_title); + + // Format the online indicator + $is_online = ($cur_post['is_online'] == $cur_post['poster_id']) ? ''.$lang_topic['Online'].'' : $lang_topic['Offline']; + + if ($pun_config['o_avatars'] == '1' && $cur_post['use_avatar'] == '1' && $pun_user['show_avatars'] != '0') + { + if ($img_size = @getimagesize($pun_config['o_avatars_dir'].'/'.$cur_post['poster_id'].'.gif')) + $user_avatar = ''; + else if ($img_size = @getimagesize($pun_config['o_avatars_dir'].'/'.$cur_post['poster_id'].'.jpg')) + $user_avatar = ''; + else if ($img_size = @getimagesize($pun_config['o_avatars_dir'].'/'.$cur_post['poster_id'].'.png')) + $user_avatar = ''; + } + else + $user_avatar = ''; + + // We only show location, register date, post count and the contact links if "Show user info" is enabled + if ($pun_config['o_show_user_info'] == '1') + { + if ($cur_post['location'] != '') + { + if ($pun_config['o_censoring'] == '1') + $cur_post['location'] = censor_words($cur_post['location']); + + $user_info[] = '
    '.$lang_topic['From'].': '.pun_htmlspecialchars($cur_post['location']); + } + + $user_info[] = '
    '.$lang_common['Registered'].': '.date($pun_config['o_date_format'], $cur_post['registered']); + + if ($pun_config['o_show_post_count'] == '1' || $pun_user['g_id'] < PUN_GUEST) + $user_info[] = '
    '.$lang_common['Posts'].': '.$cur_post['num_posts']; + + // Now let's deal with the contact links (E-mail and URL) + if (($cur_post['email_setting'] == '0' && !$pun_user['is_guest']) || $pun_user['g_id'] < PUN_GUEST) + $user_contacts[] = ''.$lang_common['E-mail'].''; + else if ($cur_post['email_setting'] == '1' && !$pun_user['is_guest']) + $user_contacts[] = ''.$lang_common['E-mail'].''; + + if ($cur_post['url'] != '') + $user_contacts[] = ''.$lang_topic['Website'].''; + } + + if ($pun_user['g_id'] < PUN_GUEST) + { + $user_info[] = '
    IP: '.$cur_post['poster_ip'].''; + + if ($cur_post['admin_note'] != '') + $user_info[] = '
    '.$lang_topic['Note'].': '.pun_htmlspecialchars($cur_post['admin_note']).''; + } + } + // If the poster is a guest (or a user that has been deleted) + else + { + $username = pun_htmlspecialchars($cur_post['username']); + $user_title = get_title($cur_post); + + if ($pun_user['g_id'] < PUN_GUEST) + $user_info[] = '
    IP: '.$cur_post['poster_ip'].''; + + if ($pun_config['o_show_user_info'] == '1' && $cur_post['poster_email'] != '' && !$pun_user['is_guest']) + $user_contacts[] = ''.$lang_common['E-mail'].''; + } + + // Generation post action array (quote, edit, delete etc.) + if (!$is_admmod) + { + if (!$pun_user['is_guest']) + $post_actions[] = '
  • '.$lang_topic['Report'].''; + + if ($cur_topic['closed'] == '0') + { + if ($cur_post['poster_id'] == $pun_user['id']) + { + if ((($start_from + $post_count) == 1 && $pun_user['g_delete_topics'] == '1') || (($start_from + $post_count) > 1 && $pun_user['g_delete_posts'] == '1')) + $post_actions[] = '
  • '.$lang_topic['Delete'].''; + if ($pun_user['g_edit_posts'] == '1') + $post_actions[] = '
  • '.$lang_topic['Edit'].''; + } + + if (($cur_topic['post_replies'] == '' && $pun_user['g_post_replies'] == '1') || $cur_topic['post_replies'] == '1') + $post_actions[] = '
  • '.$lang_topic['Quote'].''; + } + } + else + $post_actions[] = '
  • '.$lang_topic['Report'].''.$lang_topic['Link separator'].'
  • '.$lang_topic['Delete'].''.$lang_topic['Link separator'].'
  • '.$lang_topic['Edit'].''.$lang_topic['Link separator'].'
  • '.$lang_topic['Quote'].''; + + + // Switch the background color for every message. + $bg_switch = ($bg_switch) ? $bg_switch = false : $bg_switch = true; + $vtbg = ($bg_switch) ? ' roweven' : ' rowodd'; + + + // Perform the main parsing of the message (BBCode, smilies, censor words etc) + $cur_post['message'] = parse_message($cur_post['message'], $cur_post['hide_smilies']); + + // Do signature parsing/caching + if ($cur_post['signature'] != '' && $pun_user['show_sig'] != '0') + { + if (isset($signature_cache[$cur_post['poster_id']])) + $signature = $signature_cache[$cur_post['poster_id']]; + else + { + $signature = parse_signature($cur_post['signature']); + $signature_cache[$cur_post['poster_id']] = $signature; + } + } + +?> +
    +

    # 

    +
    +
    +
    +
    +
    +
    +
    +'."\n\t\t\t\t\t", $user_info).'
  • '."\n"; ?> +'.implode('  ', $user_contacts).''."\n"; ?> + + +
    +

    1) echo ' Re: '; ?>

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

    '."\n"; ?> +
    +
    '.$signature.'
    '."\n"; ?> + +
    +
    1) echo '

    '.$is_online.'

    '; ?>
    +
    '.implode($lang_topic['Link separator'].'', $post_actions).'
    '."\n" : '
     
    '."\n" ?> + + + + + +
    +
    + + +
    •  » 
    •  » 
    + +
    +
    + + +
    +

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

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