|
|
<?php
|
|
|
/* This is free and unencumbered software released into the public domain.
|
|
|
*
|
|
|
* Anyone is free to copy, modify, publish, use, compile, sell, or
|
|
|
* distribute this software, either in source code form or as a compiled
|
|
|
* binary, for any purpose, commercial or non-commercial, and by any
|
|
|
* means.
|
|
|
*
|
|
|
* In jurisdictions that recognize copyright laws, the author or authors
|
|
|
* of this software dedicate any and all copyright interest in the
|
|
|
* software to the public domain. We make this dedication for the benefit
|
|
|
* of the public at large and to the detriment of our heirs and
|
|
|
* successors. We intend this dedication to be an overt act of
|
|
|
* relinquishment in perpetuity of all present and future rights to this
|
|
|
* software under copyright law.
|
|
|
*
|
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
|
* IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
|
|
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
|
|
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|
|
* OTHER DEALINGS IN THE SOFTWARE.
|
|
|
*
|
|
|
* For more information, please refer to <http://unlicense.org/>
|
|
|
*/
|
|
|
|
|
|
$start_time = microtime(true);
|
|
|
$captcha_str = substr(strtr(sha1($start_time), "1234567890", "ABCDEFGHgh"), 0, 6);
|
|
|
|
|
|
// 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('ASSETS_PATH', 'assets/'); // Folder to store assets (header images, etc) in
|
|
|
* define('MAX_FILE_SIZE', 8 << 20); // Maximum image size, 8 MiB
|
|
|
* define('ADMIN_ID', '<SHA1 uid from your cookies>'); // uid that is able to delete anything
|
|
|
* define('UID_SALT', '<some string to salt uids with>');
|
|
|
* define('MAX_POSTS', 50); // Max posts after which old posts will be auto deleted. Only existing posts count, not manually deleted ones.
|
|
|
*
|
|
|
* // Database constants for PostgreSQL database
|
|
|
* $DB_HOST = 'localhost';
|
|
|
* $DB_NAME = '<db name>';
|
|
|
* $DB_USER = '<db role name>';
|
|
|
* $DB_PASSWORD = '<db role password>';
|
|
|
*
|
|
|
* You also need to make the following table:
|
|
|
*
|
|
|
* CREATE 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),
|
|
|
* trip VARCHAR(10),
|
|
|
* email VARCHAR(256),
|
|
|
* comment VARCHAR(2048),
|
|
|
* img VARCHAR(256),
|
|
|
* thumb_width INT,
|
|
|
* thumb_height INT,
|
|
|
* spoiler BOOL
|
|
|
* );
|
|
|
*
|
|
|
* CREATE TABLE access
|
|
|
* count INT,
|
|
|
* lock BOOL PRIMARY KEY DEFAULT TRUE,
|
|
|
* CONSTRAINT lock_unique CHECK(lock)
|
|
|
* );
|
|
|
*
|
|
|
* INSERT INTO access VALUES (0);
|
|
|
*
|
|
|
* Finally, you will also need ffmpeg and exiftool installed for
|
|
|
* metadata stripping and thumbnail conversion.
|
|
|
*/
|
|
|
require_once('vars.php');
|
|
|
|
|
|
//// Functions: ////
|
|
|
|
|
|
// Adds a post to the database
|
|
|
function post($name, $email, $comment, $img, $spoiler, $save_cookie, $captcha, $captcha_answer) {
|
|
|
$extensions = [
|
|
|
'image/bmp' => '.bmp',
|
|
|
'image/gif' => '.gif',
|
|
|
'image/jpeg' => '.jpg',
|
|
|
'image/pjpeg' => '.jpg',
|
|
|
'image/png' => '.png'
|
|
|
];
|
|
|
|
|
|
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
|
|
|
}
|
|
|
|
|
|
setcookie('name', $name, 0x7FFFFFFF);
|
|
|
$_COOKIE['name'] = $name;
|
|
|
|
|
|
setcookie('email', $email, 0x7FFFFFFF);
|
|
|
$_COOKIE['email'] = $email;
|
|
|
}
|
|
|
|
|
|
if($captcha != $captcha_answer || empty($captcha_answer)) {
|
|
|
if(!empty($img['tmp_name']))
|
|
|
@unlink($img['tmp_name']);
|
|
|
return 'Invalid CAPTCHA answer, copy the text on the left into the box';
|
|
|
}
|
|
|
|
|
|
// Validate and move the uploaded image file, if necessary
|
|
|
if($img['error'] != UPLOAD_ERR_OK && $img['error'] != UPLOAD_ERR_NO_FILE) {
|
|
|
if(!empty($img['tmp_name']))
|
|
|
@unlink($img['tmp_name']);
|
|
|
return 'Invalid image, error ' . $img['error'];
|
|
|
}
|
|
|
|
|
|
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
|
|
|
$img_name = time();
|
|
|
$ext = $extensions[$img['type']];
|
|
|
$target = UPLOAD_PATH . $img_name . $ext;
|
|
|
if(move_uploaded_file($img['tmp_name'], $target)) {
|
|
|
$output = null;
|
|
|
$ret = null;
|
|
|
|
|
|
if($img['type'] != 'image/bmp') {
|
|
|
// Strip EXIF data
|
|
|
exec("exiftool -overwrite_original -all:all= -tagsfromfile @ -exif:Orientation '$target'", $output, $ret);
|
|
|
if($ret != 0)
|
|
|
return 'Unable to upload image, please contact the webmaster.';
|
|
|
}
|
|
|
|
|
|
if($spoiler) {
|
|
|
$thumb_size = getimagesize(ASSETS_PATH . "spoiler.gif");
|
|
|
} else {
|
|
|
// Create thumbnail
|
|
|
exec("ffmpeg -y -loglevel error -i '$target' -filter_complex 'color=#ffccdd[c];[c][0]scale2ref[cs][0s];[cs][0s]overlay=shortest=1[o];[o]scale=min(200\,iw):-1[o];[o]scale=-1:min(100\,ih)' -frames:v 1 " . THUMB_PATH . "$img_name.jpg", $output, $ret);
|
|
|
if($ret != 0) {
|
|
|
@unlink($target);
|
|
|
return 'Unable to create thumbnail, please contact the webmaster.';
|
|
|
}
|
|
|
|
|
|
$thumb_size = getimagesize(THUMB_PATH . "$img_name.jpg");
|
|
|
}
|
|
|
} else {
|
|
|
// The new image file move failed, so delete the temporary file and return an error
|
|
|
@unlink($img['tmp_name']);
|
|
|
return 'Unable to rename 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';
|
|
|
|
|
|
// Check email
|
|
|
if(!empty($email)) {
|
|
|
if(!preg_match('/^[a-zA-Z0-9][a-zA-Z0-9\._\-&!?=#+]*@/', $email)) {
|
|
|
return 'Invalid email address';
|
|
|
} else {
|
|
|
$domain = preg_replace('/^[a-zA-Z0-9][a-zA-Z0-9\._\-&!?=#+]*@/', '', $email);
|
|
|
if(!checkdnsrr($domain))
|
|
|
return 'Invalid email address';
|
|
|
}
|
|
|
}
|
|
|
|
|
|
$trip_name = trip_name($name);
|
|
|
|
|
|
// Add post to database
|
|
|
$query = 'INSERT INTO posts (user_id, name, trip, email, comment, img, thumb_width, thumb_height, spoiler) ' .
|
|
|
'VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)';
|
|
|
$params = [
|
|
|
empty($uid) ? NULL : $uid,
|
|
|
empty($trip_name['name']) ? 'Anonymous' : htmlspecialchars($trip_name['name']),
|
|
|
empty($trip_name['trip']) ? NULL : htmlspecialchars($trip_name['trip']),
|
|
|
empty($email) ? NULL : $email,
|
|
|
empty($comment) ? NULL : htmlspecialchars($comment),
|
|
|
empty($target) ? NULL : basename($target),
|
|
|
$thumb_size[0],
|
|
|
$thumb_size[1],
|
|
|
$spoiler ? 'T' : 'F'
|
|
|
];
|
|
|
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 "<a href=\"#p{$match[1]}\">{$match[0]}</a>";
|
|
|
else
|
|
|
return "<del>{$match[0]}</del>";
|
|
|
}
|
|
|
|
|
|
// Prints the post list
|
|
|
function show_posts() {
|
|
|
$query = 'SELECT post_id, user_id, name, trip, email, comment, img, thumb_width, thumb_height, spoiler, 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 '<form action="' . $_SERVER['PHP_SELF'] . '#bottom" method="post">';
|
|
|
while($row = pg_fetch_array($result)) {
|
|
|
echo "<div><div id=\"p{$row['post_id']}\" class=\"post\">";
|
|
|
|
|
|
$time_rel = time_ago_en($row['post_time']);
|
|
|
$time_abs = date('Y-m-d H:m (T)', strtotime($row['post_time']));
|
|
|
|
|
|
echo '<div class="posthead">';
|
|
|
if((!empty($row['user_id']) && ($row['user_id'] == $_COOKIE['uid'])) || (!empty(ADMIN_ID) && ($_COOKIE['uid'] == ADMIN_ID))) {
|
|
|
echo '<input type="checkbox" name="delete[]" value="' . $row['post_id'] . '" /> ';
|
|
|
$show_delete = TRUE;
|
|
|
}
|
|
|
|
|
|
echo '<strong class="name">';
|
|
|
if(!empty($row['email']))
|
|
|
echo "<a href=\"mailto:{$row['email']}\">{$row['name']}</a>";
|
|
|
else
|
|
|
echo $row['name'];
|
|
|
echo '</strong>';
|
|
|
if(!empty($row['trip']))
|
|
|
echo "<span class=\"trip\">◆{$row['trip']}</span>";
|
|
|
echo " <span title=\"$time_abs\">$time_rel</span> ";
|
|
|
echo "<a href=\"#p{$row['post_id']}\">#{$row['post_id']}</a> ";
|
|
|
|
|
|
// 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 "<a href=\"#p{$ref['post_id']}\">>>{$ref['post_id']}</a> ";
|
|
|
if(!empty($row['img'])) {
|
|
|
$bytesize = bytesize(filesize(UPLOAD_PATH . $row['img']));
|
|
|
echo '<div>File:';
|
|
|
echo '<a href="' . UPLOAD_PATH . $row['img'] . '" target="_blank">' . $row['img'] . "</a> ($bytesize)</div>";
|
|
|
}
|
|
|
echo '</div>';
|
|
|
|
|
|
echo '<div class="postbody clearfix">';
|
|
|
if(!empty($row['img'])){
|
|
|
echo '<a href="' . UPLOAD_PATH . $row['img'] . '" target="_blank">';
|
|
|
$thumb_path = ($row['spoiler'] == 't') ? (ASSETS_PATH . 'spoiler.gif') : (THUMB_PATH . preg_replace('/\.(?:png|gif|bmp)$/', '.jpg', $row['img']));
|
|
|
echo "<img src=\"$thumb_path\" alt=\"{$row['img']}\" width=\"{$row['thumb_width']}\" height=\"{$row['thumb_height']}\" />";
|
|
|
echo '</a>';
|
|
|
}
|
|
|
|
|
|
// Process quotes, links, and newlines
|
|
|
if(!empty($row['comment'])) {
|
|
|
$comment = $row['comment'];
|
|
|
$comment = preg_replace('/^>(?!>\d).+/m', '<strong class="quote">$0</strong>', $comment);
|
|
|
$comment = preg_replace('/(?:https?|mailto|tel|ftp):[^\s,]+/m', '<a href="$0" target="_blank">$0</a>', $comment);
|
|
|
$comment = preg_replace_callback('/>>\s*(\d+)/', 'quote_link', $comment);
|
|
|
$comment = str_replace("\n", "<br />", $comment);
|
|
|
echo "<div>$comment</div>";
|
|
|
}
|
|
|
echo '</div></div></div>';
|
|
|
}
|
|
|
|
|
|
pg_free_result($result);
|
|
|
|
|
|
if($show_delete)
|
|
|
echo '<p><input type="submit" name="submit" value="Delete" /></p>';
|
|
|
echo '</form>';
|
|
|
}
|
|
|
|
|
|
// 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());
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// https://stackoverflow.com/a/9619947
|
|
|
function time_ago_en($time) {
|
|
|
if(!is_numeric($time))
|
|
|
$time = strtotime($time);
|
|
|
|
|
|
$periods = ['second', 'minute', 'hour', 'day', 'week', 'month', 'year', 'age'];
|
|
|
$lengths = [60, 60, 24, 7, 4.35, 12, 100];
|
|
|
|
|
|
$now = time();
|
|
|
|
|
|
$difference = $now - $time;
|
|
|
if($difference <= 10 && $difference >= 0)
|
|
|
return $tense = 'just now';
|
|
|
else if($difference > 0)
|
|
|
$tense = 'ago';
|
|
|
else if($difference < 0)
|
|
|
$tense = 'later';
|
|
|
|
|
|
for($j = 0; $difference >= $lengths[$j] && $j < count($lengths)-1; $j++) {
|
|
|
$difference /= $lengths[$j];
|
|
|
}
|
|
|
|
|
|
$difference = round($difference);
|
|
|
|
|
|
$period = $periods[$j] . ($difference >1 ? 's' :'');
|
|
|
return "{$difference} {$period} {$tense} ";
|
|
|
}
|
|
|
|
|
|
// Pretty size for bytes
|
|
|
function bytesize($bytes) {
|
|
|
if($bytes == 1) {
|
|
|
return "1 Byte";
|
|
|
} else if($bytes < (1 << 10)) {
|
|
|
return "{$bytes} Bytes";
|
|
|
} else if($bytes < (1 << 20)) {
|
|
|
return round($bytes / (1 << 10), 0) . " KiB";
|
|
|
} else if($bytes < (1 << 30)) {
|
|
|
return round($bytes / (1 << 20), 0) . " MiB";
|
|
|
} else {
|
|
|
return round($bytes / (1 << 30), 0) . " GiB";
|
|
|
}
|
|
|
}
|
|
|
|
|
|
function trip_name($name) {
|
|
|
$split = explode('#', $name);
|
|
|
$name = array_shift($split);
|
|
|
if(empty($split[0]))
|
|
|
return ['name' => $name];
|
|
|
|
|
|
$key = implode('#', $split);
|
|
|
$salt = substr($key . 'H.', 1, 2);
|
|
|
$salt = preg_replace('/[^\.-z]/', '.', $salt);
|
|
|
$salt = strtr($salt, ':;<=>?@[\\]^_`', 'ABCDEFGabcdef');
|
|
|
$trip = crypt($key, $salt);
|
|
|
$trip = substr($trip, -10);
|
|
|
return [
|
|
|
'name' => $name,
|
|
|
'trip' => $trip
|
|
|
];
|
|
|
}
|
|
|
|
|
|
function header_image($mobile) {
|
|
|
$path = ASSETS_PATH . 'header';
|
|
|
if($mobile)
|
|
|
$path .= '/mobile';
|
|
|
$files = glob("$path/*.gif");
|
|
|
if(empty($files))
|
|
|
return '';
|
|
|
return $files[array_rand($files)];
|
|
|
}
|
|
|
|
|
|
//// code start ////
|
|
|
|
|
|
// Connect to the database
|
|
|
$dbc = pg_connect("host=$DB_HOST dbname=$DB_NAME user=$DB_USER password=$DB_PASSWORD")
|
|
|
or die('Could not connect: ' . pg_last_error());
|
|
|
|
|
|
$access_count = 0;
|
|
|
{
|
|
|
pg_query('UPDATE access SET count=count+1;') or die('Query failed ' . pg_last_error());
|
|
|
$res = pg_query('SELECT count FROM access') or die('Query failed: ' . pg_last_error());
|
|
|
$access_count = pg_fetch_array($res)['count'];
|
|
|
}
|
|
|
|
|
|
if($_POST['submit'] == 'Post') {
|
|
|
// Grab the data from the POST
|
|
|
$name = trim($_POST['name']);
|
|
|
$email = trim($_POST['email']);
|
|
|
$comment = trim($_POST['comment']);
|
|
|
$img = $_FILES['img'];
|
|
|
$spoiler = isset($_POST['spoiler']) && !empty($_FILES['img']['tmp_name']);
|
|
|
$save_cookie = isset($_POST['save_cookie']);
|
|
|
$captcha = trim($_POST['captcha']);
|
|
|
$captcha_answer = trim($_POST['captcha_answer']);
|
|
|
|
|
|
$err = post($name, $email, $comment, $img, $spoiler, $save_cookie, $captcha, $captcha_answer);
|
|
|
if($err == "") {
|
|
|
# Redirect to latest post
|
|
|
$query = 'SELECT post_id FROM posts ORDER BY posts.post_time DESC LIMIT 1';
|
|
|
$result = pg_query($query) or die('Query failed: ' . pg_last_error());
|
|
|
|
|
|
$row = pg_fetch_array($result);
|
|
|
if($row) {
|
|
|
pg_close($dbc);
|
|
|
header("Location: {$_SERVER['PHP_SELF']}#p{$row['post_id']}", true, 303);
|
|
|
die();
|
|
|
}
|
|
|
}
|
|
|
} else if($_POST['submit'] == 'Delete' && !empty($_COOKIE['uid'])) {
|
|
|
foreach($_POST['delete'] as $id) {
|
|
|
cleanup($id);
|
|
|
}
|
|
|
} else {
|
|
|
$name = $_GET['name'];
|
|
|
$email = $_GET['email'];
|
|
|
$comment = $_GET['comment'];
|
|
|
}
|
|
|
|
|
|
$mobile = preg_match('/Mobile|Nintendo DSi/', $_SERVER['HTTP_USER_AGENT']);
|
|
|
if($mobile) {
|
|
|
$headerW = 192;
|
|
|
$headerH = 50;
|
|
|
} else {
|
|
|
$headerW = 384;
|
|
|
$headerH = 100;
|
|
|
}
|
|
|
?>
|
|
|
<!DOCTYPE html
|
|
|
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
|
|
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
|
|
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
|
|
<head>
|
|
|
<meta http-equiv="content-type" content="text/html;charset=utf-8" />
|
|
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
|
<meta name="theme-color" content="#DBA9B9" />
|
|
|
|
|
|
<title>BBS | ピケ.コム</title>
|
|
|
|
|
|
<link rel="alternate" type="application/rss+xml" title="RSS feed" href="/rss.php" />
|
|
|
|
|
|
<link href="<?php echo ASSETS_PATH . 'style.css'; ?>" rel="stylesheet" />
|
|
|
</head>
|
|
|
<body class="center">
|
|
|
<center>
|
|
|
<img class="center" src="<?php echo header_image($mobile); ?>" alt="BBS.ピケ.コム" width="<?php echo $headerW; ?>" height="<?php echo $headerH; ?>" />
|
|
|
</center>
|
|
|
|
|
|
<p>
|
|
|
[<a href="#bottom">bottom</a>]
|
|
|
[<a href="<?php echo $_SERVER['PHP_SELF']; ?>">reload</a>]
|
|
|
[<a href="?source">source</a>]
|
|
|
[<a href="rss.php">feed</a>]
|
|
|
[<a href="rss.php?source">feed source</a>]
|
|
|
</p>
|
|
|
|
|
|
<hr />
|
|
|
|
|
|
<form enctype="multipart/form-data" method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>#newpost">
|
|
|
<input type="hidden" name="MAX_FILE_SIZE" value="<?php echo MAX_FILE_SIZE; ?>" />
|
|
|
<div id="newpost" class="center">
|
|
|
<h2>New Post</h2>
|
|
|
|
|
|
<div class="postbody">
|
|
|
<?php if($mobile) { ?>
|
|
|
<label for="name">Name:</label> (Optional)
|
|
|
<br />
|
|
|
<input id="name" name="name" value="<?php echo htmlspecialchars($name ? : $_COOKIE['name']); ?>" />
|
|
|
<br />
|
|
|
<br />
|
|
|
|
|
|
<label for="email">Email:</label> (Optional)
|
|
|
<br />
|
|
|
<input id="email" name="email" value="<?php echo htmlspecialchars($email ? : $_COOKIE['email']); ?>" />
|
|
|
<br />
|
|
|
<br />
|
|
|
|
|
|
<label for="comment">Comment:</label>
|
|
|
<br />
|
|
|
<textarea id="comment" name="comment" rows="10" cols="27"><?php echo htmlspecialchars($comment); ?></textarea>
|
|
|
<br />
|
|
|
<br />
|
|
|
|
|
|
<label for="img">Image:</label> (Limit: <?php echo MAX_FILE_SIZE >> 10; ?> KiB)
|
|
|
<br />
|
|
|
<input type="file" id="img" name="img" />
|
|
|
<br />
|
|
|
<br />
|
|
|
|
|
|
<label for="spoiler">Spoiler:</label>
|
|
|
<input type="checkbox" id="spoiler" name="spoiler" <?php if($spoiler) echo 'checked'; ?> />
|
|
|
<br />
|
|
|
<br />
|
|
|
|
|
|
<label for="captcha">CAPTCHA:</label></td>
|
|
|
<br />
|
|
|
<code><?php echo $captcha_str; ?></code>
|
|
|
<input id="captcha" name="captcha" />
|
|
|
<input type="hidden" name="captcha_answer" value="<?php echo $captcha_str; ?>" />
|
|
|
<br />
|
|
|
<br />
|
|
|
|
|
|
<label for="save-cookie">Save cookie:</label>
|
|
|
<input type="checkbox" id="save-cookie" name="save_cookie" <?php if($_COOKIE['uid']) echo 'checked'; ?> />
|
|
|
<br />
|
|
|
(Allows deleting your own posts)
|
|
|
<br />
|
|
|
<br />
|
|
|
|
|
|
<input type="submit" value="Post" name="submit" />
|
|
|
<?php } else { ?>
|
|
|
<table>
|
|
|
<tr>
|
|
|
<td><label for="name">Name:</label></td>
|
|
|
<td><input id="name" name="name" value="<?php echo htmlspecialchars($name ? : $_COOKIE['name']); ?>" /> (Optional)</td>
|
|
|
</tr>
|
|
|
<tr>
|
|
|
<td><label for="email">Email:</label></td>
|
|
|
<td><input id="email" name="email" value="<?php echo htmlspecialchars($email ? : $_COOKIE['email']); ?>" /> (Optional)</td>
|
|
|
</tr>
|
|
|
<tr>
|
|
|
<td><label for="comment">Comment:</label></td>
|
|
|
<td><textarea id="comment" name="comment" rows="10" cols="40"><?php echo htmlspecialchars($comment); ?></textarea></td>
|
|
|
</tr>
|
|
|
<tr>
|
|
|
<td><label for="img">Image:</label></td>
|
|
|
<td><input type="file" id="img" name="img" /> (Limit: <?php echo MAX_FILE_SIZE >> 10; ?> KiB)</td>
|
|
|
</tr>
|
|
|
<tr>
|
|
|
<td><label for="spoiler">Spoiler:</label></td>
|
|
|
<td><input type="checkbox" id="spoiler" name="spoiler" <?php if($spoiler) echo 'checked'; ?> /></td>
|
|
|
</tr>
|
|
|
<tr>
|
|
|
<td><label for="captcha">CAPTCHA:</label></td>
|
|
|
<td>
|
|
|
<code><?php echo $captcha_str; ?></code>
|
|
|
<input id="captcha" name="captcha" />
|
|
|
<input type="hidden" name="captcha_answer" value="<?php echo $captcha_str; ?>" />
|
|
|
</td>
|
|
|
</tr>
|
|
|
<tr>
|
|
|
<td><label for="save-cookie">Save cookie:</label></td>
|
|
|
<td><input type="checkbox" id="save-cookie" name="save_cookie" <?php if($_COOKIE['uid']) echo 'checked'; ?> /> (Allows deleting your own posts)</td>
|
|
|
</tr>
|
|
|
<tr>
|
|
|
<td></td>
|
|
|
<td><input type="submit" value="Post" name="submit" /></td>
|
|
|
</tr>
|
|
|
</table>
|
|
|
<?php } ?>
|
|
|
|
|
|
<?php if(!empty($err)) echo "<p><strong class=\"error\">$err</strong></p>"; ?>
|
|
|
</div>
|
|
|
</div>
|
|
|
</form>
|
|
|
|
|
|
<hr />
|
|
|
|
|
|
<?php
|
|
|
show_posts();
|
|
|
|
|
|
pg_close($dbc);
|
|
|
?>
|
|
|
|
|
|
<hr />
|
|
|
|
|
|
<div id="footer">
|
|
|
<p>
|
|
|
Welcome to my silly little bulletin board. It's primarily intended
|
|
|
for personal use transferring images from devices where that is
|
|
|
otherwise difficult, however anyone is free to use it.
|
|
|
Old posts are automatically deleted once there are more than
|
|
|
<?php echo MAX_POSTS; ?>, anything inappropriate will be deleted.
|
|
|
</p>
|
|
|
<p>
|
|
|
Formatting is very simple, just <strong class="quote">>quote</strong>
|
|
|
by starting a line with > and link to other posts with two >
|
|
|
and the post number, <del>>>1</del>. No other formatting is
|
|
|
supported besides URLs being automatically made into hyperlinks.
|
|
|
You may provide a name and/or email address when posting if you wish
|
|
|
to identify yourself, however it is not required. A tripcode can be
|
|
|
used by writing "Name#Password" in the name field, note that only
|
|
|
the first 8 characters are used.
|
|
|
</p>
|
|
|
<p>
|
|
|
The year is <?php echo date('Y'); ?>, but no ©. This page was generated in <?php printf("%.2f", microtime(true) - $start_time); ?> seconds and has been accessed <?php echo $access_count; ?> times.
|
|
|
</p>
|
|
|
</div>
|
|
|
|
|
|
<p id="bottom">
|
|
|
[<a href="#top">top</a>]
|
|
|
[<a href="<?php echo $_SERVER['PHP_SELF']; ?>">reload</a>]
|
|
|
[<a href="?source">source</a>]
|
|
|
[<a href="rss.php">feed</a>]
|
|
|
[<a href="rss.php?source">feed source</a>]
|
|
|
</p>
|
|
|
|
|
|
<p>
|
|
|
<a href="//validator.w3.org/check?uri=<?php echo urlencode('http://' . $_SERVER['SERVER_NAME'] . $_SERVER['PHP_SELF']); ?>" target="_blank"><img src="//www.w3.org/Icons/valid-xhtml10" alt="Valid XHTML 1.0 Transitional" height="31" width="88" /></a>
|
|
|
<a href="https://jigsaw.w3.org/css-validator/check/referer"><img style="border:0;width:88px;height:31px" src="https://jigsaw.w3.org/css-validator/images/vcss" alt="Valid CSS!" /></a>
|
|
|
</p>
|
|
|
</body>
|
|
|
</html>
|