add spoof postime feature

このコミットが含まれているのは:
たかし 2023-08-24 15:32:34 +00:00
コミット f1ca7e1148
9個のファイルの変更126行の追加7行の削除

ファイルの表示

@ -21,6 +21,7 @@ default_config('ENABLE_LOGIN', false);
default_config('ENABLE_REGISTER', false);
default_config('ENABLE_ATTACHMENT', false);
default_config('ENABLE_IMAGE', false);
default_config('ENABLE_SPOOF_TIME', false);
default_config('THREAD_SIZE', 100);
default_config('POST_LIMIT', 500);

ファイルの表示

@ -56,6 +56,9 @@ define('SITEBASE', '/');
## 投稿を有効にする。
define('ENABLE_POST', true);
## 投稿時間のごまかしを有効にする。
# define('ENABLE_SPOOF_TIME', true);
## ゲスト(未ログインユーザーの投稿)を有効にする。
define('ENABLE_GUEST', true);

ファイルの表示

@ -8,7 +8,7 @@
// "{$datetime}.id{$id}.us{$userid}.to{未使用}.th{$thread_id}.txt"
// 内訳:
// $datetime: 投稿日時(ISO形式、タイムゾーンは「Z」固定)
// $id: 投稿ID(0から始まり1づつ増える)
// $id: 投稿ID(0から始まり1づつ増える・又は・md5ハッシュ)
// $userid: 投稿者$id (ゲストの場合「-」が入る)
// {未使用}: 現在は常に「-」が入る
// $thread_id: 返信先スレッドの投稿ID (返信以外なら「-」が入る)
@ -184,7 +184,17 @@ function search_post($options = []) {
$key = null;
$value = null;
$now = date('Y-m-d\\TH:i:s\\Z');
$files = glob(POST_DIR . $pattern);
$files = array_filter(
$files,
function ($v) use($now) {
$datetime = substr(basename($v), 0, 20);
return $datetime <= $now;
},
ARRAY_FILTER_USE_BOTH
);
if (!$thread) {
$files = array_reverse($files);
}
@ -228,7 +238,7 @@ function search_post($options = []) {
return compact('post_list', 'total', 'page', 'pager', 'last_page');
}
function add_post($userid, $title, $body, $attachment_id, $file_hash, &$post_id_ref, $thread_id) {
function add_post($userid, $title, $body, $attachment_id, $file_hash, &$post_id_ref, $thread_id, $spooftime) {
// TODO:引数は配列の方が良い?
// TODO:$post_id_refの参照渡しはイマイチ
if ($thread_id !== NOREPLY_ID) {
@ -247,9 +257,19 @@ function add_post($userid, $title, $body, $attachment_id, $file_hash, &$post_id_
$fp_lock = start_post_lock();
if ($fp_lock === false) { return ['ファイルの取得に失敗。']; }
$id = count_post() + 1;
if (ENABLE_SPOOF_TIME) {
$id = md5(mt_rand(0, 9) . count_post() . $userid . $title . $body);
} else {
$id = count_post() + 1;
}
$datetime = date('Y-m-d\\TH:i:s\\Z');
if ($spooftime) {
$dto = new DateTime('+' . (mt_rand(60 * 60 * 3, 60 * 60 * 24)) . 'seconds');
$datetime = $dto->format('Y-m-d\\TH:i:s\\Z');
$dto = null;
} else {
$datetime = date('Y-m-d\\TH:i:s\\Z');
}
$file = "{$datetime}.id{$id}.us{$userid}.to-.th{$thread_id}.txt";
if ($body !== '.' || $file_hash === '') {

ファイルの表示

@ -58,6 +58,7 @@ function do_post() {
// Allow attachment only post
$body = '.';
}
$spooftime = (int)mbtrim($_POST['spooftime'] ?? '');
$thread_id = $_POST['thread_id'] ?? null;
$error_title = validate_post_title($title);
@ -105,10 +106,14 @@ function do_post() {
}
$userid = $_SESSION['user']['id'] ?? GUEST_ID;
$errors = add_post($userid, $title, $body, $attachment_id, $file_hash ?? '', $post_id, $thread_id);
$errors = add_post($userid, $title, $body, $attachment_id, $file_hash ?? '', $post_id, $thread_id, $spooftime);
if ($errors) { return on_error(500, $errors); }
$_SESSION['messages'] = ['投稿完了。'];
if ($spooftime) {
$_SESSION['messages'] = ['予約投稿完了。'];
} else {
$_SESSION['messages'] = ['投稿完了。'];
}
http_response_code(301);
header('Location: ' . sitebase('post/?id=' . $post_id));
}

ファイルの表示

@ -169,6 +169,20 @@ a:hover
/* class */
.spooftime-text
{
font-style: italic;
font-weight: 400;
}
:checked ~ .spooftime-text
{
background: #0ff;
color: #000;
font-style: normal;
font-weight: 600;
}
.form-li-submit
{
text-align: right;

ファイルの表示

@ -38,7 +38,12 @@ function sanitize_bio($s) {
}
function validate_post_id($s) {
if ((string)(int)$s !== $s || $s < 0) { return ['投稿 ID が不正。']; }
if (
((string)(int)$s !== $s || $s < 0)
&& !preg_match('/[0-9a-z]{32}/', $s)
) {
return ['投稿 ID が不正。'];
}
return [];
}

ファイルの表示

@ -26,6 +26,9 @@ $view['form'] = $view['form'] ?? [];
<li><label for="TITLE">件名 (省略可)・Title (Optional)</label> <input type="text" id="TITLE" name="title">
<?php endif; ?>
<li><label for="BODY">本文 (500文字以内)・Text (500)</label> <textarea id="BODY" name="body" cols="40" rows="5"></textarea>
<?php if (ENABLE_SPOOF_TIME): ?>
<li><label><input type="checkbox" name="spooftime" value="1"> <b class="spooftime-text">チェックONで投稿時間をごまかす(ランダムで3H~24H後に予約投稿)</b></label></li>
<?php endif; ?>
<?php if (ENABLE_IMAGE): ?>
<li><label for="ATTACHMENT">画像 (gif/jpg/png・上限 500kb )</label> <input type="file" id="ATTACHMENT" name="attachment">
<?php endif; ?>

33
view/post_form.php ノーマルファイル
ファイルの表示

@ -0,0 +1,33 @@
<?php if (isset($view['form']['thread_id']) && $view['form']['thread_id'] >= 0): ?>
<h2 id="REPLY_FORM">返信</h2>
<?php endif; ?>
<?php if (!can_post()): ?>
<?php if (!post_limited()): ?>
<ul>
<li>書き込み制限中。</li>
</ul>
<?php endif; ?>
<?php elseif ($view['thread_size_over'] ?? false): ?>
<ul>
<li>スレッドの長さが上限の <?= THREAD_SIZE ?> 件に到達。</li>
</ul>
<?php else: ?>
<?php
$view['form'] = $view['form'] ?? [];
?>
<form method="POST" action="/post/">
<ul>
<?php if (!(isset($view['form']['thread_id']) && $view['form']['thread_id'] >= 0)): ?>
<li><label for="TITLE">件名 (省略可)</label> <input type="text" id="TITLE" name="title">
<?php endif; ?>
<li><label for="BODY">本文 (500文字以内)</label> <textarea id="BODY" name="body" cols="40" rows="5"></textarea>
<li class="form-li-submit">
<?php if (isset($view['form']['thread_id']) && $view['form']['thread_id'] >= 0): ?>
<input type="hidden" name="thread_id" value="<?= htmlspecialchars($view['form']['thread_id'] ?? '') ?>">
<button type="submit">返信</button>
<?php else: ?>
<button type="submit">書き込む</button>
<?php endif; ?>
</ul>
</form>
<?php endif; ?>

35
view/post_list.php ノーマルファイル
ファイルの表示

@ -0,0 +1,35 @@
<?php
$reply_list_mode = isset($view['reply_list_mode']) && $view['reply_list_mode'];
?>
<?php if (isset($view['post_list'])): ?>
<?php foreach ($view['post_list'] as $i => $post):
$no = $i + 2;
$title = htmlspecialchars($post['title'] ?? '');
$username = htmlspecialchars($post['username']);
$userid = htmlspecialchars($post['userid']);
$time = $post['time']; // safe
$detail_url = htmlspecialchars($post['detail_url']);
$user_url = htmlspecialchars($post['user_url']);
$body = $post['body']; // body is valid html
$is_guest = $post['is_guest'] ?? false;
$thread_id = $post['thread_id'] ?? '';
$thread_title = $post['thread_title'] ?? '';
$thread_url = $post['thread_url'] ?? '';
?>
<dl<?= ($reply_list_mode ? ' id="' . $no . '"' : '') ?>>
<?php if ($title > ''): ?>
<dt><b>件名:<a href="<?= $detail_url ?>"><?= $title ?></a></b></dt>
<?php endif; ?>
<?php if ($is_guest): ?>
<dt><?= $reply_list_mode ? "$no " : '' ?> <b><?= $username ?></b> <a class="post-time" href="<?= $detail_url ?>"><?= $time ?></a></dt>
<?php else: ?>
<dt><?= $reply_list_mode ? "$no " : '' ?> <b><a href="<?= $user_url ?>"><?= $username ?></a></b> @<?= $userid ?> <a class="post-time" href="<?= $detail_url ?>"><?= $time ?></a></dt>
<?php endif; ?>
<?php if ($thread_id >= 0 && !$reply_list_mode): ?>
<dd>RE:<a href="<?= $thread_url ?>"><?= $thread_title ?></a></dd>
<?php endif; ?>
<dd><?= $body ?></dd>
<dd><a href="<?= $detail_url ?>#REPLY_FORM">返信</a></dd>
</dl>
<?php endforeach; ?>
<?php endif; ?>