// =================================================================== // START CONFIGURATION $database = 'database-001'; // Your TXT file name as database. $per_page = 10; // The number of items you want to display per page. $time_zone = 'Europe/Amsterdam'; // Look at `date_default_timezone_set()` $max_length_name = 60; // Maximum character length for guest name $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.', 'message_missing' => 'Please enter your message.', 'max_length_name' => 'Maximum character length for guest name is ' . $max_length_name, '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 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 for character length limit if(strlen($name) > $max_length_name) $error .= "

" . $messages['max_length_name'] . "

"; 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" . "\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_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. // ---------------------------------------------------------------------------------------- /** * 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"; } ?>

=