*/ // Return source code if(isset($_GET['source'])) { header("Content-Type: text/plain"); die(file_get_contents(basename($_SERVER['PHP_SELF']))); } /* vars.php should contain the following, but with your variables as needed: * * // Application constants * define('UPLOAD_PATH', 'image/'); // Folder to save images to * define('THUMB_PATH', 'thumb/'); // Folder to save thumbnails to * define('MAX_FILE_SIZE', 8 << 20); // Maximum image size, 8 MiB * define('ADMIN_ID', ''); // uid that is able to delete anything * define('UID_SALT', ''); * define('MAX_POSTS', 50); // Max posts after which old posts will be auto deleted. Only existing posts count, not manually deleted ones. * define('DISCORD_WEBHOOK', 'https://discord.com/api/webhooks//'); // A message will be sent to this webhook on post, for easier moderation * * // Database constants for PostgreSQL database * $DB_HOST = 'localhost'; * $DB_NAME = ''; * $DB_USER = ''; * $DB_PASSWORD = ''; * * You also need to make the following table: * * CEATE TABLE posts ( * post_id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, * post_time TIMESTAMPTZ NOT NULL DEFAULT NOW(), * user_id VARCHAR(40), * name VARCHAR(256), * comment VARCHAR(2048), * img VARCHAR(256) * ); */ require_once('vars.php'); //// Functions: //// // Adds a post to the database function post($name, $comment, $img, $save_cookie) { $extensions = [ 'image/bmp' => '.bmp', 'image/gif' => '.gif', 'image/jpeg' => '.jpg', 'image/pjpeg' => '.jpg', 'image/png' => '.png' ]; // Validate and move the uploaded image file, if necessary if(!empty($img['tmp_name'])) { if((($img['type'] == 'image/gif') || ($img['type'] == 'image/jpeg') || ($img['type'] == 'image/pjpeg') || ($img['type'] == 'image/png') || ($img['type'] == 'image/bmp')) && ($img['size'] > 0) && ($img['size'] <= MAX_FILE_SIZE)) { if($img['error'] == 0) { // Move the file to the target upload folder $name = time(); $target = UPLOAD_PATH . $name . $extensions[$img['type']]; if(move_uploaded_file($img['tmp_name'], $target)) { $output = null; $ret = null; exec("ffmpeg -y -loglevel error -i '$target' -vf 'scale=-1:min(100\,ih)' " . THUMB_PATH . "$name.jpg", $output, $ret); if($ret != 0) { // The new image file move failed, so delete the temporary file and return an error @unlink($target); return 'Unable to create thumbnail, please contact the webmaster.'; } } else { // The new image file move failed, so delete the temporary file and return an error @unlink($img['tmp_name']); return 'Unable to upload image, please contact the webmaster.'; } } } else { // The image is not valid, so delete the temporary file and return an error @unlink($img['tmp_name']); return 'Your image must be a PNG, GIF, JPEG, or BMP image file no greater than ' . (MAX_FILE_SIZE >> 10) . ' KiB.'; } } if(strlen($comment) > 2048) return 'Comment must be 2048 or fewer characters'; if(empty($comment) && empty($target)) return 'You must include an image and/or a comment'; if($save_cookie) { $uid = $_COOKIE['uid']; if(empty($uid)) { $uid = sha1(time() . $img['tmp_name'] . $_SERVER['REMOTE_ADDR'] . UID_SALT); setcookie("uid", $uid, 0x7FFFFFFF); $_COOKIE['uid'] = $uid; // so that the checkbox is checked } } // Add post to database $query = "INSERT INTO posts (user_id, name, comment, img) VALUES ($1, $2, $3, $4)"; $params = [ empty($uid) ? NULL : $uid, empty($name) ? 'Anonymous' : htmlspecialchars($name), empty($comment) ? NULL : htmlspecialchars($comment), empty($target) ? NULL : basename($target) ]; webhook($params[1], $params[2], 'http://' . $_SERVER['SERVER_NAME'] . dirname($_SERVER['PHP_SELF']) . $target); // Send to discord for moderation pg_query_params($query, $params) or die('Query failed: ' . pg_last_error()); return ""; // Success, no error } // Regex callback, makes >>quotes into links function quote_link($match) { $query = "SELECT post_id FROM posts WHERE post_id=$1"; $result = pg_query_params($query, [$match[1]]) or die('Query failed: ' . pg_last_error()); $row_count = pg_num_rows($result); pg_free_result($result); if($row_count > 0) return "{$match[0]}"; else return "{$match[0]}"; } // Prints the post list function show_posts() { $query = 'SELECT post_id, user_id, name, comment, img, TO_CHAR(post_time, \'YYYY-MM-DD HH24:MI (TZ)\') AS post_time FROM posts ORDER BY posts.post_time'; $result = pg_query($query) or die('Query failed: ' . pg_last_error()); // Clean up old posts $row_count = pg_num_rows($result); if($row_count > MAX_POSTS) { for($i = 0; $i < $row_count - MAX_POSTS; $i++) { $row = pg_fetch_array($result); cleanup($row['post_id']); } } // Print posts $show_delete = FALSE; echo '
'; while($row = pg_fetch_array($result)) { echo "
"; echo ''; if((!empty($row['user_id']) && ($row['user_id'] == $_COOKIE['uid'])) || (!empty(ADMIN_ID) && ($_COOKIE['uid'] == ADMIN_ID))) { echo ' '; $show_delete = TRUE; } echo "{$row['name']} {$row['post_time']} "; echo "#{$row['post_id']} "; // Find references $post_id = pg_escape_string($row['post_id']); $ref_query = "SELECT post_id FROM posts WHERE comment LIKE '%>>$post_id%' ORDER BY post_time"; $ref_result = pg_query_params($ref_query, []) or die('Query failed: ' . pg_last_error()); while($ref = pg_fetch_array($ref_result)) echo ">>{$ref['post_id']} "; echo ''; if(!empty($row['img'])){ echo ''; echo '' . $row['img'] . ''; echo ''; } // Process quotes, links, and newlines if(!empty($row['comment'])) { $comment = $row['comment']; $comment = preg_replace('/^>(?!>\d).+/m', '$0', $comment); $comment = preg_replace('/(?:https?|mailto|tel|ftp):[^\s]+/m', '$0', $comment); $comment = preg_replace_callback('/>>\s*(\d+)/', quote_link, $comment); $comment = str_replace("\n", "
", $comment); echo "

$comment

"; } echo '
'; } pg_free_result($result); if($show_delete) echo '

'; echo '
'; } // Removes a post from the database and its image function cleanup($id, $force = FALSE) { $query = "SELECT user_id, img FROM posts WHERE post_id=$1"; $result = pg_query_params($query, [$id]) or die('Query failed: ' . pg_last_error()); $row = pg_fetch_array($result); pg_free_result($result); if($force || $row['user_id'] == $_COOKIE['uid'] || (!empty(ADMIN_ID) && ($_COOKIE['uid'] == ADMIN_ID))) { unlink(UPLOAD_PATH . $row['img']); $query = "DELETE FROM posts WHERE post_id=$1"; pg_query_params($query, [$id]) or die('Query failed: ' . pg_last_error()); } } // Sends a webhook to Discord function webhook($name, $message, $img) { if(empty(DISCORD_WEBHOOK)) return; $data = [ 'username' => $name, 'embeds' => [ [ 'title' => "New Post", 'url' => 'http://' . $_SERVER['SERVER_NAME'] . $_SERVER['PHP_SELF'] . '#bottom', 'description' => $message, 'image' => [ 'url' => $img ] ] ] ]; $curl = curl_init(DISCORD_WEBHOOK); curl_setopt($curl, CURLOPT_HEADER, false); curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); curl_setopt($curl, CURLOPT_HTTPHEADER, array("Content-Type: application/json")); curl_setopt($curl, CURLOPT_POST, true); curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($data)); curl_exec($curl); $status = curl_getinfo($curl, CURLINFO_HTTP_CODE); curl_close($curl); if($status != 204) die("Error: Sending webhook failed with status $status."); } ?> BBS | ピケ.コム

[bottom]

New Post
(Limit: > 10; ?> KiB)
/> (Allows deleting your own posts)
$err"; ?>

Old posts are automatically deleted once there are more than , anything inappropriate will be deleted.

[top] [reload] [source]

Valid XHTML 1.0 Transitional