Location: PHPKode > projects > YapGB - Yet Another PHP GuestBook > yapgb.php
<?php
//header('P3P: CP="CAO PSA OUR"');
/* If you're planning on using your YapGB guestbook from an external
 * site (e. g. within a frame), and you have problems with confirmation
 * code (when working as an image) not appearing, uncomment the line above
 * by deleting the two slashes (/) at the beginning of the header() instruction.
 */

/*
~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~
~= YapGB - Yet Another Php Guest Book                              =~
~= v0.7.3                                                          =~
~= Mar 18th, 2007                                                  =~
~= http://yapgb.sourceforge.net/                                   =~
~=-----------------------------------------------------------------=~
~= AUTHOR:                                                         =~
~=    José Jorge Enríquez Rodríguez                                =~
~=    hide@address.com (redirected email)                    =~
~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~
~= YapGB is a free guestbook system written in PHP that does not   =~
~= require a database, entries are stored in a plain text file.    =~
~= Copyright (C) 2003-2005 José Jorge Enríquez Rodríguez           =~
~=                                                                 =~
~= 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                                             =~
~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~
~= yapgb.php: main YapGB file.                                     =~
~=                                                                 =~
~= CHANGES                                                         =~
~= v0.7.3:                                                         =~
~= - IP logging (thanks to Martin Debef). Visitor's IP address is  =~
~=   stored into databse when signing the guestbook.               =~
~= - Added the possibility to ban IP addresses.                    =~
~= - Confirmation code is showed as image even when GD library is  =~
~=   not available.                                                =~
~= v0.7.2:                                                         =~
~= - Added a header() instruction at the top of this file, it is a =~
~=   "fix" to the problem in IE 6 that won't show the confirmation =~
~=   code (as image) if the guestbook was included from an external=~
~=   site. It is disabled by default, you'll need to uncomment the =~
~=   instruction in order to use it.                               =~
~= v0.7.1                                                          =~
~= - Bug fixed, confirmation code was always required even if      =~
~=   $cfgEnableConfirmationCode variable was set to 0.             =~
~= v0.7:                                                           =~
~= - Added the option to require the user to enter a confirmation  =~
~=   code. Since other "anti-spam" options didn't work completely, =~
~=   this would be the best option to prevent automated guestbook  =~
~=   signing.                                                      =~
~= - A small bug that allowed empty name/message entries has been  =~
~=   corrected.                                                    =~
~= - New error notification method, errors are shown on the sign   =~
~=   page, the script reloads it and automatically fills in the    =~
~=   data again (so entered data is not lost as before).           =~
~= v0.6.1:                                                         =~
~= - Added the creation of some session vars in sign page. These   =~
~=   variables are checked before saving a new entry. This will    =~
~=   help assure the user visited our sign page first.             =~
~= v0.6:                                                           =~
~= - Added moderation option.                                      =~
~= - Added log and debug flags (useless).                          =~
~= - Added two spam protection features:                           =~
~=   + Trusted URIs (posts are only saved if coming from a trusted =~
~=     URI).                                                       =~
~=   + Minimum "waiting" time between posts.                       =~
~= v0.5:                                                           =~
~= - Added the use of smilies and BBCode functions.                =~
~= v0.4.2:                                                         =~
~= - Improved email and url addresses checking. Now it shows the   =~
~=   appropiate message when the address is not correct.           =~
~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~
*/

// Debug?
//define("YAPGB_DEBUG_MODE", true);
// Log?
//define( "YAPGB_LOG_ENABLED", true );

# Disable magic quotes at runtime.
# It is used to avoid the addition of back slashes (\) to user's input.
set_magic_quotes_runtime( 0 );

# Configuration options.
require_once( "gbconfig.php" );
# Functions file.
require_once( "gbfunc.php" );
# Language file
require_once( "lang/$cfgLangFile" );

#NEW IN 0.7.3beta
#Block bad users first
if (gbDenyBadIP($_SERVER[ "REMOTE_ADDR" ])) {
	die($strErrorDenyBadIP);
}

# Get action to perform and page number, it is done this way so that
# YapGB works with older versions of PHP (the $HTTP_XX_VARS array).
if ( !empty( $_GET ) ) {
	if ( isset( $_GET[ "action" ] ) )  $action = $_GET[ "action" ];
	if ( isset( $_GET[ "page" ] ) )    $page = $_GET[ "page" ];
}
else if ( !empty( $HTTP_GET_VARS ) ) {
	if ( isset( $HTTP_GET_VARS[ "action" ] ) )  $action = $HTTP_GET_VARS[ "action" ];
	if ( isset( $HTTP_GET_VARS[ "page" ] ) )  $page = $HTTP_GET_VARS[ "page" ];
}

if ( isset( $_POST["action"] ) )  $action = $_POST[ "action" ];
else if ( isset( $HTTP_POST_VARS[ "action" ] ) )  $action = $_POST[ "action" ];

# Make sure we have page number.
if ( !isset( $page ) or $page == 0 )  $page = 1;

session_start();


# Show sign form
if ( $action == "sign") {
	/* New in version 0.6.1
	 * Now we set a session var if user has visited our sign page.
	 */
	//session_start();
	$userIP = $_SERVER[ "REMOTE_ADDR" ];
	$pathTranslated = $_SERVER[ "PATH_TRANSLATED" ];
	$_SESSION[ "SIGN_PAGE_VISITED" ] = true;
	$_SESSION[ "USER_IP" ] = $userIP;
	$_SESSION[ "KEY" ] = md5( $pathTranslated );

	# Get the signing form template
	$signTemplate = gbLoadTemplate( "temp_sign.html" );
	# New in v0.7
	# Needed since temp_sign.html now uses GB_TAGS as values for
	# input fields.
	#NEW IP
	$signTemplate = gbSwapEntryGBTags( $signTemplate, -1, "", -1, "", "http://", "", "", false );
	# Swap global GB_TAGS
	$signTemplate = gbSwapGlobalGBTags( $signTemplate );
	
	// Confirmation code
	if ( $cfgEnableConfirmationCode ) {
		$signTemplate = gbSwapConfirmCode( $signTemplate );
	}

	# Show sign form
	echo $signTemplate;
}
# Add a new entry
else if ( $action == "add") {
	# Security and anti-spam:
	# who's calling the script?
	$referer = $_SERVER[ "HTTP_REFERER" ];
	
	# New since v0.7
	# The script does not stop on errors, rather it writes them
	# to string $error and shows them at the end.
	$error = "";

	// if trusted URIs is on
	if ( $cfgEnableTrustedURIs ) {
		// Check wheteher referer is a trusted one
		/* New in 0.6.1: referer must be non-empty, it (almost) disables the check
		 * referer feature, but I've found that some browsers do not create the
		 * HTTP_REFERER var correctly (if it does not exist, users won't be able
		 * to sign guestbook at all!)
		 */
		if ( !gbCheckReferer( $referer ) && $referer != '' ) {
			if ( defined( "YAPGB_LOG_ENABLED" ) ) gbLog( "Not trusted referer." );
			$error .= "<b>$strError:</b> $strErrorNoTrustedReferer<br />\n";
			//die( "<b>$strError:</b> $strErrorNoTrustedReferer" );
		}
		/* New in version 0.6.1
		 * HTTP_REFERER depends on user agent (it means spammers can bypass referer checks),
		 * so we can not rely on it (and also because of the "fix" above).
		 * Now we check for our session variables set when showing the signing page.
		 */
		//session_start();
		$userIP = $_SERVER[ "REMOTE_ADDR" ];
		$pathTranslated = $_SERVER[ "PATH_TRANSLATED" ];

		if ( !isset( $_SESSION[ "SIGN_PAGE_VISITED" ] )
				|| $userIP != $_SESSION[ "USER_IP" ]
				|| md5( $pathTranslated ) != $_SESSION[ "KEY" ] )
		{
			if ( defined( "YAPGB_LOG_ENABLED" ) ) gbLog( "Not coming from signing form." );
			$error .= "<b>$strError:</b> $strErrorNoTrustedReferer<br />\n";
		}
	}

	# Get entry variables
	if ( !empty( $_POST ) ) {
		if ( isset($_POST[ "name" ]) )    $name  = $_POST[ "name" ];
		if ( isset($_POST[ "email" ]) )   $email = $_POST[ "email" ];
		if ( isset($_POST[ "url" ]) )     $url   = $_POST[ "url"];
		if ( isset($_POST[ "message" ]) ) $message = $_POST[ "message" ];
		if ( isset($_POST[ "confirmCode" ]) ) $confirmCode = $_POST[ "confirmCode" ];
	}
	else if ( !empty( $HTTP_POST_VARS ) ) {
		if ( isset( $HTTP_POST_VARS[ "name" ] ) )    $name  = $HTTP_POST_VARS[ "name" ];
		if ( isset( $HTTP_POST_VARS[ "email" ] ) )   $email = $HTTP_POST_VARS[ "email" ];
		if ( isset( $HTTP_POST_VARS[ "url" ] ) )     $url   = $HTTP_POST_VARS[ "url" ];
		if ( isset( $HTTP_POST_VARS[ "message" ] ) ) $message = $HTTP_POST_VARS[ "message" ];
		if ( isset( $HTTP_POST_VARS[ "confirmCode" ] ) ) $confirmCode = $HTTP_POST_VARS[ "confirmCode" ];
	}
	#NEW IP
	$ip = $_SERVER[ "REMOTE_ADDR" ];

	if ( $cfgEnableConfirmationCode ) {
		//session_start();
		if ( !isset( $_SESSION[ "CONFIRM_CODE" ] ) ) {
			if ( defined( 'YAPGB_LOG_ENABLED' ) ) gbLog( "Confirmation code didn't exist." );
			$error .= "<b>$strError:</b> " . $strErrorWrongConfirmationCode .'<br />'. $strErrorNoTrustedReferer ."<br />\n";
		}
		else {
			if ( strtoupper( $confirmCode ) != $_SESSION[ 'CONFIRM_CODE' ] ) {
				//echo "Code entered: $confirmCode<br />Code required: {$_SESSION[ 'CONFIRM_CODE' ]}<br />";
				if ( defined( 'YAPGB_LOG_ENABLED' ) ) gbLog( "Wrong confirmation code" );
				$error .= "<b>$strError:</b> ". $strErrorWrongConfirmationCode ."<br />\n";
			}
		}
	}

	// current time
	$date = time();

	// Enable access to session vars
	// If user has already posted, check whether he/she can post again
	if ( isset( $_SESSION["LASTPOST_TIME"] ) ) {
		if ( $date - $_SESSION[ "LASTPOST_TIME" ] <= $cfgSecondsToWait ) {
			if ( defined( "YAPGB_LOG_ENABLED" ) ) gbLog( "User tried to post again. Current time: $date, last post: ".$_SESSION["LASTPOST_TIME"] );
			$error .= "<b>$strError:</b> $strErrorAlreadyPosted<br />\n";
		}
	}

	# [ Bug corrected]: 'bad users' were able to post entries
	# with empty name/message fields.
	# Name and message are required, check whether they are empty.
	if ( !isset( $name ) or empty( $name ) ) {
		$error .= "<b>$strError:</b> $strErrorNameRequired<br />\n";
	}
	if ( !isset( $message ) or empty( $message ) ) {
		$error .= "<b>$strError:</b> $strErrorMessageRequired<br />\n";
	}

	# Email checking. First we check whether the email field is
	# not empty, if so, it does not matter if email is not
	# required, we check for a correct email address and if it is
	# not, we show an error message.
	# Changes since v0.7: check first if email is required
	if ( $cfgRequireEmail ) {
		if ( empty( $email ) ) {
			$error .= "<b>$strError:</b> $strErrorEmailRequired<br />\n";
		}
		else if ( !gbCheckEmail( $email ) ) {
			$error .= "<b>$strError:</b> $strErrorEmailIncorrect<br />\n";
		}
	}
	
	# Url checking.
	# Valid url addresses could be:
	# http://www.hewop.com/~yapgb
	# www.hewop.com/~yapgb (the script will add "http://" at the start)
	# If url field is not empty and it is not equal to just "http://"
	# Since v0.7: check first whether url is required
	if ( $cfgRequireUrl ) {
		if ( empty( $url ) ) {
			$error .= "<b>$strError:</b> $strErrorUrlRequired<br />\n";
		}
		else if ( !gbCheckUrl( $url ) ) {
			if ( gbCheckUrl( "http://$url" ) ) {
				$url = "http://$url";
			}
			else {
				$error .= "<b>$strError:</b> $strErrorUrlIncorrect<br />\n";
			}
		}
	}
	
	# If there were errors
	if ( !empty( $error ) ) {
		$signTemplate = gbLoadTemplate( "temp_sign.html" );
		if ( get_magic_quotes_gpc() ) {
			$name = stripslashes( $name );
			$email = stripslashes( $email );
			$url = stripslashes( $url );
			$message = stripslashes( $message );
		}
		// Put back info entered before by the user
		#NEW IP
		$signTemplate = gbSwapEntryGBTags( $signTemplate, -1, $name, -1, $email, $url, $message, "0", false );
		$signTemplate = gbSwapGlobalGBTags( $signTemplate );
		
		if ( $cfgEnableConfirmationCode ) {
			$signTemplate = gbSwapConfirmCode( $signTemplate );
		}

		// Let the user know about the errors
		$signTemplate = str_replace( "<!--GB_SIGNERRORS-->", $error, $signTemplate );		
		// Show sign form and exit.
		die( $signTemplate );
	}

	# Format fields. These functions need revision.
	$name = gbCleanField( $name );
	$email = gbCleanField( $email );
	$url = gbCleanField( $url );
	$message = gbCleanMessage( $message );

	# Format new entry. I'm planning on changing the date format.
	#NEW IP
	$newEntry = $name."|".$date."|".$email."|".$url."|".$message."|".$ip."|[end]";

	# If moderate entries is enabled, save new entry to moderation file.
	$file = 	$cfgEnableModeration ? $cfgModerateFile : $cfgEntriesFile;

	$fp = fopen( $file, "a" ) or die( $strErrorOpeningFile );
	fwrite( $fp, $newEntry."\n" );
	fclose( $fp );

	// Remember when user posted
	$_SESSION[ "LASTPOST_TIME" ] = $date;

	// and unset our sign page session vars
	unset( $_SESSION[ "SIGN_PAGE_VISITED" ] );
	unset( $_SESSION[ "USER_IP" ] );
	unset( $_SESSION[ "KEY" ] );
	unset( $_SESSION[ "CONFIRM_CODE" ] );

	# If notify of new post enabled.
	if ( $cfgNewPostNotify ) {
		gbNewPostNotify( $name, $email, $url, $message );
	}

	/* New in version 0.6.1
	 * If $cfgShowSignSuccesful is set to 0, go to main page.
	 * If it is set to 1, load a temp_succesful.html page and
	 * show it to the user.
	 */
	if ( !$cfgShowSuccesfulPage ) {
		header( "Location: $cfgGBIndex" );
		exit();
	}
	else {
		$succesfulPage = gbLoadTemplate( "temp_signsuccesful.html" );
		#NEW IP
		$succesfulPage = gbSwapEntryGBTags( $succesfulPage, -1, $name, $date, $email, $url, $message, $ip, false );
		$succesfulPage = gbSwapGlobalGBTags( $succesfulPage );
		die( $succesfulPage );
	}
}
# Generate confirmation code image
else if ( $action == 'genimg' ) {
	gbGenerateConfirmImage();
}
# View entries
else {
	# Read entries file into an array.
	$text = file( $cfgEntriesFile );
	# How many entries we have.
	$lines = count( $text );

	$entryTemplate = gbLoadTemplate( "temp_message.html" );

	# Most recent post first.
	if ( $cfgNewestPostFirst ) {
		$limitValue = $lines - $page * $cfgEntriesPerPage;

		for ( $i = $limitValue + $cfgEntriesPerPage - 1; ( $i >= $limitValue ) && ( $i >= 0 ); $i-- ) {
			#NEW IP
			list( $name, $date, $email, $url, $message, $ip ) = explode( "|", $text[ $i ] );

			# Censoring functions.
			$name = gbSwapBadWords( $name );
			$name = gbCutLongWords( $name ); // New call in 0.6.2
			//$email = gbSwapBadWords($email);
			//$url = gbSwapBadWords($url);
			$message = gbSwapBadWords( $message );
			$message = gbCutLongWords( $message );

			# If hide email option is enabled.
			# Not executed here anymore, it is done in the gbSwapEmailUrlLinks() function
			//if ( $cfgHideEmail ) $email = gbHideEmail($email);

			# If BBCode is enabled.
			if ( $cfgEnableBBCode ) $message = gbSwapBBCode( $message );
			# If smilies are enabled.
			if ( $cfgEnableSmilies ) $message = gbSwapSmilies( $message );
			$entries .= $entryTemplate;
			# Swap entry GB_TAGS
			#NEW IP
			$entries = gbSwapEntryGBTags( $entries, $i, $name, $date, $email, $url, $message, $ip, false );
		}
	}
	# Oldest post first.
	else {
		$limitValue = $page * $cfgEntriesPerPage;
		for ( $i = $limitValue - $cfgEntriesPerPage; $i < $limitValue; $i++ ) {
			#NEW IP
			list( $name, $date, $email, $url, $message, $ip ) = explode( "|", $text[ $i ] );
			$name = gbSwapBadWords( $name );
			$message = gbSwapBadWords( $message );
			if ( $cfgHideEmail ) $email = gbHideEmail( $email );

			$entries .= $entryTemplate;
			#NEW IP
			$entries = gbSwapEntryGBTags( $entries, $i, $name, $date, $email, $url, $message, $ip, false );
		}
	}

	# Load main page template.
	$bodyContent = gbLoadTemplate( "temp_body.html" );
	# Swap global GB_TAGS
	$bodyContent = gbSwapGlobalGBTags( $bodyContent );
	# Put entries into main page.
	$bodyContent = str_replace( '<!--GB_ENTRIES-->', $entries, $bodyContent );
	#Pagination
	$bodyContent = gbSwapPaginationGBTags( $bodyContent, $lines, $page );
	
	# Show main page
	echo $bodyContent;
}

session_write_close();
?>
Return current item: YapGB - Yet Another PHP GuestBook