bibis/public/post/index.php

124 行
3.7 KiB
PHP

<?php
require_once(__DIR__ . '/../../require.php');
if ($_SERVER['REQUEST_METHOD'] === 'GET') {
do_get();
}
else if ($_SERVER['REQUEST_METHOD'] === 'POST') {
do_post();
}
function do_get() {
// Post (thread) detail
$id = $_GET['id'] ?? '';
if (validate_post_id($id)) { return on_error(400, ['URL が不正。']); }
$post = load_post_by_id($id);
if (!$post) { return on_error(400, ['書き込みが存在しない']); }
$view['post'] = $post;
$thread_id = $post['thread_id'];
$is_reply = $thread_id != '';
if ($is_reply) {
$result = search_post(['key' => 'thread', 'value' => $thread_id]);
$total = $result['total'];
}
else {
$result = search_post(['key' => 'thread', 'value' => $id]);
$total = $result['total'];
$view['total'] = $total;
$view['reply_list'] = $result['post_list'];
}
$view['thread_size_over'] = ($total + 1 >= THREAD_SIZE);
$result = null;
$view['form'] = ['thread_id' => $is_reply ? $thread_id : $id];
$view['is_future_post'] = $post['is_future'];
output_html($view, ['header.php', 'post.php', 'post-form.php']);
}
function do_post() {
// Add new post (too long, sorry)
if (!can_post()) {
if (!post_limited()) { return on_error(403, ['書き込み不可。']); }
else { return on_error(403, ['書き込み停止中。']); }
}
$errors = check_csrf_token();
if ($errors) { return on_error(400, $errors); }
$has_file = ($_FILES['attachment']['error'] ?? 4) !== 4;
$title = mbtrim($_POST['title'] ?? '');
$body = mbtrim($_POST['body'] ?? '');
if ($has_file && $body === '') {
// Allow attachment only post
$body = '.';
}
$spooftime = (int)mbtrim($_POST['spooftime'] ?? '');
$thread_id = $_POST['thread_id'] ?? null;
$error_title = validate_post_title($title);
if (!$error_title) {
$title = sanitize_post_title($title);
$error_title = validate_post_title($title);
}
$error_body = validate_post_body($body);
if (!$error_body) {
$body = sanitize_post_body($body);
$error_body = validate_post_body($body);
}
$errors = array_merge($error_title, $error_body);
if ($errors) { return on_error(400, $errors); }
if ($thread_id !== null) {
$error_thread_id = validate_post_id($thread_id);
if ($error_thread_id) { return on_error(400, $error_thread_id); }
$thread = load_post_by_id($thread_id);
if (!$thread) { return on_error(400, ['返信先の書き込みが存在しない。']); }
if (($thread['thread_id'] ?? '') !== '') { return on_error(400, ['返信先がスレッドではない。']); }
// TODO:予約投稿への返信もブロックするべきだが、投稿者本人しかIDを知り得ないから優先度低。
}
else {
$thread_id = NOREPLY_ID;
}
$result = search_post(['key' => 'thread', 'value' => $thread_id]);
$total = $result['total'];
$result = null;
// FIXME:返信前後でロックするべきでは?
if ($thread_id !== NOREPLY_ID && $total + 1 >= THREAD_SIZE) { return on_error(400, ['返信の上限を超過。']); }
$attachment_id = null;
if (ENABLE_IMAGE && $has_file) {
$errors = check_uploaded_image('attachment');
if ($errors) { return on_error(400, $errors); }
$file_hash = md5(file_get_contents($_FILES['attachment']['tmp_name']));
$attachment_id = md5(uniqid('', true) . 'bibis');
$errors = save_uploaded_image('attachment', $attachment_id);
if ($errors) { return on_error(500, $errors); }
}
$userid = $_SESSION['user']['id'] ?? GUEST_ID;
$errors = add_post($userid, $title, $body, $attachment_id, $file_hash ?? '', $post_id, $thread_id, $spooftime);
if ($errors) { return on_error(500, $errors); }
if ($spooftime) {
$_SESSION['messages'] = ['予約投稿完了。'];
} else {
$_SESSION['messages'] = ['投稿完了。'];
}
http_response_code(301);
header('Location: ' . sitebase('post/?id=' . $post_id));
}