#!/usr/bin/perl
# Last change: PFB 6 May 2001 10:55 pm
#############################################################################
# POD Documentation (more POD text at the end of the file)
=head1 PROGRAM NAME AND AUTHOR
futureforum_include.cgi
FutureForum include file
created for version 1.32 of 'futureforum.cgi'
by Peter F. Brown - peterbrown@futurerealm.com
FutureRealm Productions - futurerealm.com
=head1 COPYRIGHT
Copyright 1999-2000 Peter F. Brown (FutureRealm Productions)
and complies with the GNU GENERAL PUBLIC LICENSE
and is released as "Open Source Software".
NO WARRANTY IS OFFERED FOR THE USE OF THIS SOFTWARE
=head1 BUG REPORTS AND SUPPORT
Send bug reports to peterbrown@futurerealm.com.
Visit the author's web site at 'worldcommunity.com'
to view information about support, customer quotes,
a resume link, and fees for custom Perl/MySQL programming.
=head1 OBTAINING THE LATEST VERSION
==> Get the most recent version of this program at:
http://futurerealm.com/opensource
=head1 NOTES
THIS IS THE INCLUDE FILE
EDIT THESE VARS TO SET UP A FORUM
YOU SHOULDN'T HAVE TO EDIT THE VARS IN THE MAIN FILE
................................................................
VARS are in THREE sections, below:
1) Forum Specific Vars
2) System Vars
3) HTML routines (which also contain Forum Specific Vars)
!!! Make sure you check ALL THREE sections !!!
See the 'NOTE ON MULTIPLE FORUM METHODOLOGY' at the end of this file
=cut
##############################################################################
# FORUM SPECIFIC VARIABLES
# that affect the use of separate forum tables
# main script name (NOT the name of THIS file; set the name of this file
# in the main file.)
# => you do this to use multiple files for multiple forums.
$script_name = 'futureforum.cgi'; # important!! used for form posting
$db_host = 'localhost';
$db_main = 'forum'; # name of database (not table)
$db_table = 'forum'; # each forum should have its own table
# with its own public user and password
# this should use the 'table_priv' table
# (although it doesn't have to)
# PASSWORD METHODOLOGY:
# don't put the password in this script, which might get redistributed.
# INSTEAD... create a file called '.www.my.cnf' for password access
# place the '.www.my.cnf' file OUTSIDE your web document root.
# NOTE!!! don't use '.www.my.cnf' for your root or admin password,
# because the file has to be set to 644, for web access.
# For your admin password, use '.my.cnf', set to 600
# so only you can access it.
# If someone can figure out a more secure method, please email me.
# .my.cnf is documented in the MySQL documentation, quite extensively.
# a sample .www.my.cnf file looks like:
#...................................
# [forum]
# user=mysql_user_name
# password=mysql_password
#...................................
# Substitute the user name and password as you have them set up
# in your mysql permissions tables (user and db) (see notes below)
$cnf_file = "../../../.www.my.cnf";
# this option tells the script to look in this 'group' in the .www.my.cnf file
# for the password
$user_group = 'software';
# $user and $password are pulled in from that file
# if you use multiple boards, you could place multiple
# password variables in that file, and use the appropriate one
# in each main script file.
# e.g: '[music]' could be the group used for a music forum
# e.g: '[tech]' could be used for a tech forum
###################
$forum_admin = "peterbrown\@worldcommunity.com";
$forum_title = 'World Community Network Open Source Software';
# You'll need to edit the topics array:
# we use an array (not a hash) so that
# 1. menu options will sort according to the array order
# 2. if we used a hash for labels, with different values,
# the values would show up in the message topic field,
# and would be different, which we don't want.
@topics = (
'Any Topic',
'FutureSQL Bugs',
'FutureSQL Suggestions',
'FutureSQL - Any Topic',
'FutureForum Bugs',
'FutureForum Suggestions',
'FutureForum - Any Topic',
'Forum Administration',
'Forum Help',
'Other Software',
'To Do Items',
'Suggestions',
'Programming Issues',
'Other'
);
#################################################################################
# GENERAL SYSTEM VARIABLES THAT YOU CAN EDIT
# $ENV{'MYSQL_UNIX_PORT'} is used because we have multiple instances
# of the MySQL daemon running on our host (worldcommunity.com) and each
# instance has its own mysql.sock file - Therefore the script needs to find it.
#!!! If you use the normal MySQL installation, then COMMENT OUT this line
# $ENV{'MYSQL_UNIX_PORT'} = "/virtual/home/worldcommunity.com/mysql/mysql.sock";
# mail program
#............................................
# you may wish to use:
# $mailprog = "/usr/lib/sendmail -t -n";
$mailprog = "/var/qmail/bin/qmail-inject -h";
# menu colors
#..............................
$top_menu_bg = "steelblue";
$top_menu_fg = "#ffffff";
$menu_bg = "#99ccff";
$menu_fg = "#000080";
# image url
# => prepend this to the images in the main file
# => the code only uses the $variables,
# so the url must already be inside the variable.
# => note the inserted / backslash in the IMAGE variables.
# => this is the URL (NOT the physical directory path)
$img_url = '.'; # current directory uses '.'
$help_url_path = '.';
$help_url = "$help_url_path/help.htm";
$help_url_text = "! Need HELP using this Forum? :-) Click Here !";
# gif files used by the system
# you can use jpegs if you wish
$new_gif = "$img_url/new_tiny.gif"; # used for new messages
$dot_clea = "$img_url/dot_clea.gif"; # used for vertical
# 'single pixel gif' spacing
$bg_img = "$img_url/sandston.gif"; # background image for html pages
# gif files for message level bullets
#......................................
@gif = (
"$img_url/blue.gif",
"$img_url/cyan.gif",
"$img_url/green.gif",
"$img_url/yellow.gif",
"$img_url/purple.gif"
);
$gif_limit = @gif; # (number of elements in array)
#........................................................................
# GIF IMAGE CODE will loop around and use the first element
# when the level hits the limit + 1 (etc, etc.)
# ==> you can use any number of gif or jpeg elements
# ==> the order of the array will create the order of the indented images
# text variables
#......................................
# used for indenting
$tab = ' ';
$max_body_length= 10000; # prevents overloading
# defaults for the display of the date, time and topic in message lists
$show_date = 'y';
$show_time = 'n';
$show_topic = 'y';
# variables to control display of NEW messages
$new_days = 14; # number of days to call messages 'new'
# which records are viewed as default
$default_view = "new"; # ("new" or "all")
$minimum_new = 20; # minimum new records required in order to display
# only new records; otherwise... see below
$limit_num = 50; # this controls how many messages get displayed
# if the new string doesn't display at least the
# amount in the $minimum_new value.
# The script will then
# re-query the database, using the $all_str, but
# limiting the results to the $limit_num
# I put @badwords in a separate file, rather
# than placing the array in this file, because, frankly,
# I dislike having to repeatedly view the list of
# uninspiring words. Shall we all say 'Ick' together? :-)
# It's also easier if someone doesn't want to bother with
# the badword file, because if it doesn't exist, it's ok.
# Someone may wish to simply declare the array here, and
# comment out the call to the other file.
# (the array should be named '@badwords')
$badwordcheck = 'yes'; # set to 'yes' or anything else if you don't want it
@badwords = ();
$badwordfile = './badwords.pl';
if ( $badwordcheck eq 'yes' )
{
if ( -e $badwordfile )
{
require "$badwordfile";
my $badwords_str = join ' ', @badwords;
if ( $badwords_str !~ /\w+/ )
{
$badwordcheck = 'no';
}
}
else
{
$badwordcheck = 'no';
}
}
#################################################################################
### HTML ROUTINES ###
#################################################################################
# html_header
sub html_header
{
# a good method of indenting:
# use any number of
because it only # indents from the left, not each side like#............................................................ #~; } ################################################################################# # forum_header sub forum_header { # ==> FORUM_HEADER # ... it has the text appearing at the top of the top page #................................................................................ print qq~print qq~
- # body... #
$forum_title ~; } ################################################################### # html_footer sub html_footer { # it would be nice :-) to keep at least some of this footer intact. print qq~
This Forum is Open Source Software
FutureForum $version
© 2001 The World Community Network
All Rights Reserved Worldwide
worldcommunity.com
Source is provided at:
http://worldcommunity.com/opensource/futureforum/futureforum.htm
Welcome to the
World Community Network Open Source Software Support Forum!This forum is for the support of all of our Open Source Software, including "FutureSQL" and "FutureForum" (which runs this forum.)
This support forum is for the discussion of any issues revolving around our Open Source software, such as support, installation, brilliant ideas, etc.
You can find all of our software at worldcommunity.com/opensource.
Source for FutureForum is provided at worldcommunity.com/opensource/futureforum/futureforum.htm.
Please email any comments or diatribes :-) to peterbrown\@worldcommunity.com
(or post them here -- I'll get them.) Thank you! ~; } ################################################################################# # top_page_header sub top_page_header { # this is the code to display the top page BEFORE the message list # you can modify this routine and the top_page_footer, to # CHANGE the format of the top page # !!! remember that the MESSAGES are displayed in BETWEEN the two routines print qq~
$forum_title ~; &display_menu; print qq~ ~; &forum_header; print qq~
Messages~; &add_msg_form; &html_footer; } ################################################################## # message_page_header sub message_page_header { # common header for secondary pages # note use of $forum_title in header print qq~
- ~; } ################################################################################# # top_page_footer sub top_page_footer { # this is the code to display the top page AFTER the message list print qq~
$forum_title
~; } ################################################################################# # add_msg_form sub add_msg_form { #!!! NOTE !!! # Be careful when editing this: it has many code fragments that are important # I placed it in the setup file in case someone wanted to edit the html # included throughout this subroutine print qq~
~; if ( $count_of_forum >= $max_messages ) { print qq~Forum has been Maxed Out!~; } else { if ( $msg_page ) { $post_header = "Follow Up (Your Response)"; } else { $post_header = "Message"; } print qq~
It currently has $count_of_forum messages.No additional messages can be posted.
Post A $post_header in the Form Below~; } # end of count of forum test } ################################################################## # TECHNICAL POD DOCUMENTATION # keep the 1; on the line directly above the END cut mark 1; __END__ =head1 DATABASE SCHEMA Schema for the FutureForum Database The forum table in the forum database ............................................................ create table forum ( message_no int(10) unsigned not null auto_increment, parent_no int(10) unsigned not null, branch_no text not null, level int(10) unsigned not null, topic varchar(100) not null, subject varchar(100) not null, author varchar(100) not null, email varchar(100) not null, date date not null, time time not null, seconds bigint(25) not null, body text not null, responses int(10) unsigned not null, send_email varchar(1) not null, primary key (message_no), key (topic), key (subject), key (date), key (seconds), key (level), key (author) ); ............................................................ =head1 A NOTE ON MULTIPLE FORUM METHODOLOGY Since all messages are stored in tables, each forum should get its own table. But, all the forum tables can be in one MySQL database. Since each forum is accessed via this script, you have two basic choices: (let's assume you want to run two forums, as an example.) 1. Copy this script to a new name, such as 'futureforum_music.cgi', and then run it in the same directory as your other script, e.g: 'futureforum.cgi' or 'futureforum_whatever.cgi'. (You could of course use shorter script names ... (I just like using 'futureforum...cgi' (naturally :-) ))) ==> Note: You must change the 'script_name' variable, if you rename the script!!!! 2. You can also use copy the script to a different directory, and use it with the url syntax '.../forum/music/futureforum.cgi'. This may be cleaner if you have different image files, etc. Either method should work; the critical factor is that you need to set up separate tables for each forum in MySQL, and set the grant table permissions. I would recommend that you use different user names and passwords, for security. Set the 'user' table to NO permissions, and selectively grant the user permissions in the 'db' table. => You'll need to set up the 'table_priv' permissions, also, => which I have NOT documented here. Note that only 'Select_priv', 'Insert_priv', 'Update_priv' are set 'Y' and ONLY in the DB Table => MySQL grant permissions should be: USER TABLE: +-----------+-------------+------------------+-------------+-------------+-------------+-------------+-------------+-----------+-------------+---------------+--------------+-----------+ | Host | User | Password | Select_priv | Insert_priv | Update_priv | Delete_priv | Create_priv | Drop_priv | Reload_priv | Shutdown_priv | Process_priv | File_priv | +-----------+-------------+------------------+-------------+-------------+-------------+-------------+-------------+-----------+-------------+---------------+--------------+-----------+ | localhost | forum | ... password ... | N | N | N | N | N | N | N | N | N | N | +-----------+-------------+------------------+-------------+-------------+-------------+-------------+-------------+-----------+-------------+---------------+--------------+-----------+ DB TABLE: +-----------+--------+--------+-------------+-------------+-------------+-------------+-------------+-----------+ | Host | Db | User | Select_priv | Insert_priv | Update_priv | Delete_priv | Create_priv | Drop_priv | +-----------+--------+--------+-------------+-------------+-------------+-------------+-------------+-----------+ | localhost | forum | forum | Y | Y | Y | N | N | N | +-----------+--------+--------+-------------+-------------+-------------+-------------+-------------+-----------+ => this is NOT a tutorial on using MySQL. For that, visit 'www.mysql.com'. ............................................................ =head1 TODO LIST - add help text ....................................... future: - add user/password methodology for protected boards (public read/private write) - add admin functions (delete message, delete branch) .... deletes will affect 'responses' (number updates) - user option: emails to forum are posted - user option: email all messages to user ............................................................ =head1 PARTIAL LIST OF CURRENT FEATURES - configurable display of top page structure - routine to import old messages from wwwboard.cgi (Matt Wright's Board) - uses 'branch_no' design to keep track of 'threads' - can display top page of messages with numerous selection or sorting methods - uses MySQL database for speed and convenience (the major negative is that the body text is not viewable by search engines) - the message text is stored as pure text -- html cosmetics can be changed in the script, and the display of the messages changes accordingly - multiple board methodology (see notes below) - unlimited levels of bullet images (see notes below) - configurable max message and branch length vars (see notes) (default setting handles 1 million top level messages, 10 million total) - user option: email responses to user - options to hide topics, date, time on message listings (shortens lines) - security: has MySQL password; admin can change it - shows 'current thread' and 'parent message' on message display - blocks duplicate messages - option to view only parent threads and expand thread on top page - configurable html cosmetics - a number of sticky menu options (on selects) - uses topics in messages: uses select box to select by topic - has 'toggle menu' function on top page - simple, advanced and no menu - can select by date range and 'new' posts, and other selection criteria - sends email of each post to admin - sends response email of message to original poster - automatically displays 'new' button for recent posts; ages automatically - has security routines - maxlength of body, no html, no questionable chars ............................................................ =head1 HISTORY LIST - v1.32 - August 2, 2000 - OUCH, OUCH AND OUCH AGAIN. Through the sharp eyes of one of our users, a simple but really unfortunate bug was just squashed. By adding the code: ', send_email' after the word 'seconds' on line 796 of the main file, i.e: # OLD CODE, line 796: # seconds # NEW CODE, line 796: # seconds, # send_email a bug was fixed which prevented RESPONSES from being sent to message posters. You'd think I would have caught THAT bug, of all bugs. Mea Culpa big time. I think I didn't catch it, because I had set myself to receive the admin messages - thus I received two messages whenever I posted. I can't believe I haven't caught it in all this time. Yes... this means that posters have not been receiving replies. OUCH AND OUCH AGAIN. My sincerest apologies to all. - v1.31 - March 15, 2000 - added a function to check for bad words - v1.30 - December 11, 1999 - modified uri escape routine to include foreign letters - separated out more setup elements into the setup file, including as much html as possible. Hopefully, unless there are major code revisions, folks will be able to simply plug in the new main file without changing the setup file. (This remains to be seen.) - modified structure of top page by using tables => you can change the top page structure in the 'top_page_header' and 'top_page_footer' routines - isolated display of messages from surrounding elements - modified method of displaying message indentation. => it now uses tables for each message, with the $tab var, placed in table data cells on the left side of each table => tables seemed to be the most stable method of indentation, so I abandoned attempts to get
(Type in a message, and then hit "Preview Your Message" to see what it will look like. You'll see a new screen with a "preview" of your message. If all is correct, then hit "Post" at that screen, and your message will be saved for others to see. If you don't like it, then you'll be able to hit your "Back" button in your browser, and make corrections before it's saved permanently.) Note: The Name, Email and Subject fields can be scrolled, up to 100 characters in length.,
,$tab, or style sheets to work. All of them, even
, had serious limitations. (I didn't like
anyway, because I wanted to use custom bullets, and
is crippled that way. Time to change
?) - modified email code to allow < and > in the subject and body of email messages, while still disallowing ` and " and | => < and > are still not allowed in the database, so that html is prevented. Too many possibilities for junk. HTML chars are replaced with < and > - v1.21 - July 30, 1999 added more controls to display of new records; if there aren't enough new records to satisfy the criteria, then additional records are displayed; otherwise, the display might be empty. - v1.2 - July 22, 1999 first stable public release, changed .my.cnf to .www.my.cnf so that .my.cnf can still be used from the shell, set to 600 (you don't want to put your admin passwords in .www.my.cnf) - v1.0 beta - beta release ............................................................ =cut