// =================================================================== // START CONFIGURATION $database = 'database-001'; // Your TXT file name as database. $per_page = 5; // The number of items you want to display per page. $time_zone = 'Asia/Jakarta'; // Look at `date_default_timezone_set()` $max_length_name = 60; // Maximum character length for guest name $max_length_url = 120; // Maximum character length for guest URL $max_length_message = 1000; // Maximum character length for guest message $messages = array( 'database_missing' => 'Database not found. Created one. Please reload the page.', 'name_missing' => 'Please enter your name.', 'url_invalid' => 'Invalid URL.', 'message_missing' => 'Please enter your message.', 'math_invalid' => 'Wrong math answer.', 'max_length_name' => 'Maximum character length for guest name is ' . $max_length_name, 'max_length_url' => 'Maximum character length for guest URL is ' . $max_length_url, 'max_length_message' => 'Maximum character length for guest message is ' . $max_length_message, 'no_content' => 'No content.' ); // END CONFIGURATION // Set default timezone to adjust the timestamp. // => http://www.php.net/manual/en/function.date-default-timezone-set.php date_default_timezone_set($time_zone); // Functions to create and/or update the content of the TXT file (our database) function create_or_update_file($file_path, $data) { $handle = fopen($file_path, 'w') or die('Cannot open file: ' . $file_path); fwrite($handle, $data); } // Filter HTML outputs. // The rest will appear as plain HTML entities to prevent XSS. // => http://en.wikipedia.org/wiki/Cross-site_scripting function filter_html($data) { return preg_replace( array( '/<(\/?)(b|blockquote|br|em|i|ins|mark|q|strong|u)>/i', // Allowed HTML tags '/<center>/', // Deprecated
tag '/<\/center>/', // Deprecated
tag '/&([a-zA-Z]+|\#[0-9]+);/' // Symbols ), array( '<$1$2>', '
', '
', '&$1;' ), $data); } // Redefine database name via URL to load // Load database-002.txt => http://localhost/guestbook/index.php&data=database-002 if(isset($_GET['data'])) { $database = $_GET['data']; } // Check whether the "database" is not available. If not, create one! if( ! file_exists($database . '.txt')) { // Prevent guest to create new database via `data=database-XXX` in URL // Only administrator can do this by editing the `$database` value if( ! isset($_GET['data'])) { create_or_update_file($database . '.txt', ""); echo "

" . $messages['database_missing'] . "

"; } return false; } else { $old_data = file_get_contents($database . '.txt'); } /** * Post a message */ $error = ""; // error messages if($_SERVER['REQUEST_METHOD'] == 'POST') { $name = ""; $url = ""; $message = ""; $timestamp = date('U'); // Make sure the guest name is not empty. if(isset($_POST['name']) && ! empty($_POST['name'])) { $name = strip_tags($_POST['name']); } else { $error .= "

" . $messages['name_missing'] . "

"; } // Make sure the URL format is valid. Set its value as `-` if empty. if(isset($_POST['url']) && ! empty($_POST['url'])) { if(filter_var($_POST['url'], FILTER_VALIDATE_URL)) { $url = strip_tags($_POST['url']); } else { $error .= "

" . $messages['url_invalid'] . "

"; } } else { $url = "-"; } // Make sure the guest message is not empty. if(isset($_POST['message']) && ! empty($_POST['message'])) { $message = preg_replace( array( '/[\n\r]{4,}/', // [1] '/\n/', '/[\r\t]/', '/ {2}/', // Multiple space characters '/  |  /', '/(.*?)<\/a>/i' // Match links ), array( '

', '
', '', '  ', '  ', '$6' // Unlink all links in message content! ), $_POST['message']); $message = htmlentities($message, ENT_QUOTES, 'UTF-8'); // [2] } else { $error .= "

" . $messages['message_missing'] . "

"; } // Check the math challenge answer to prevent spam robot. if( ! isset($_POST['math']) || empty($_POST['math']) || $_POST['math'] != $_SESSION['math']) { $error .= "

" . $messages['math_invalid'] . "

"; } // Check for character length limit if(strlen($name) > $max_length_name) $error .= "

" . $messages['max_length_name'] . "

"; if(strlen($url) > $max_length_url) $error .= "

" . $messages['max_length_url'] . "

"; if(strlen($message) > $max_length_message) $error .= "

" . $messages['max_length_message'] . "

"; // If all data entered by guest is valid, insert new data! if($error === "") { $new_data = $name . "\n" . $url . "\n" . $message . "\n" . $timestamp; if( ! empty($old_data)) { create_or_update_file($database . '.txt', $new_data . "\n\n==\n" . $old_data); // Prepend data } else { create_or_update_file($database . '.txt', $new_data); // Insert data } } else { // else, print the error messages. echo $error; } } // [3] $_SESSION['guest_name'] = isset($_POST['name']) ? $_POST['name'] : ""; $_SESSION['guest_url'] = isset($_POST['url']) ? $_POST['url'] : "http://"; $_SESSION['guest_message'] = isset($_POST['message']) && $error != "" ? htmlentities($_POST['message'], ENT_QUOTES, 'UTF-8') : ""; // ---------------------------------------------------------------------------------------- // [1]. Prevent guest to type too many line break symbols. // People usually do these thing to make their SPAM messages looks striking. // [2]. Convert all HTML tags into HTML entities. This is done thoroughly for safety. // We can revert back the escaped HTML into normal HTML tags later via `filter_html()` // [3]. Save the form data into session. So if something goes wrong, the data entered // by guest will still be stored in the form after submitting. // ---------------------------------------------------------------------------------------- // Math challenge to prevent spam robot. // Current answer will be stored in `$_SESSION['math']` $x = mt_rand(1, 10); $y = mt_rand(1, 10); if($x - $y > 0) { $math = $x . ' - ' . $y; $_SESSION['math'] = $x - $y; } else { $math = $x . ' + ' . $y; $_SESSION['math'] = $x + $y; } // Testing... // echo $math . ' = ' . $_SESSION['math']; /** * Show the existing data. */ $data = file_get_contents($database . '.txt'); $current_page = isset($_GET['page']) ? $_GET['page'] : 1; $nav = ""; if( ! empty($data)) { $data = explode("\n\n==\n", $data); $total_pages = ceil(count($data) / $per_page); // Create navigation if the number of pages is more than 1. if($total_pages > 1) { for($i = 0; $i < $total_pages; $i++) { if($current_page == ($i + 1)) { $nav .= " " . ($i + 1) . ""; // Disabled navigation } else { $nav .= "
" . ($i + 1) . ""; } } } for($i = 0; $i < count($data); $i++) { $item = explode("\n", $data[$i]); // Permalink (single item) // http://localhost/guestbook/index.php&data=database-001&guest=0123456789 if(isset($_GET['guest']) && preg_match('/[0-9]+/', $_GET['guest'])) { if($item[3] == $_GET['guest']) { echo "
\n"; echo " "; echo $item[1] == "-" ? "" : ""; echo $item[0]; echo $item[1] == "-" ? "" : ""; echo "\n"; echo " "; echo ""; echo " #"; echo "\n"; echo " " . filter_html($item[2]) . "\n"; echo "
\n"; } // Normal list } else { if($i <= ($per_page * $current_page) - 1 && $i > ($per_page * ($current_page - 1)) - 1) { echo "
\n"; echo " "; echo $item[1] == "-" ? "" : ""; echo $item[0]; echo $item[1] == "-" ? "" : ""; echo "\n"; echo " "; echo ""; echo " #"; echo "\n"; echo " " . filter_html($item[2]) . "\n"; echo "
\n"; } } } } else { echo "
\n"; echo " Guestbook\n"; echo " " . $messages['no_content'] . "\n"; echo "
\n"; } ?>

=