bibis/util.php

190 行
4.4 KiB
PHP

<?php
// 共通処理
// HTTP関連
function get_fp() {
return md5(
($_SERVER['HTTP_USER_AGENT'] ?? '')
. ($_SERVER['HTTP_ACCEPT_LANGUAGE'] ?? '')
. ($_SERVER['HTTP_ACCEPT_ENCODING'] ?? '')
. ($_SERVER['HTTP_ACCEPT'] ?? '')
);
}
function has_cookie() {
return isset($_COOKIE['bibis']);
}
function on_error($code, $errors) {
http_response_code(400);
if (function_exists('bibis_http_header')) { bibis_http_header(); }
$view['errors'] = $errors;
require(__DIR__ . '/view/header.php');
exit;
}
function output_html($view, $_components) {
if (ENABLE_FAKE_ERROR) { http_response_code(400); }
if (function_exists('bibis_http_header')) { bibis_http_header(); }
foreach ($_components as $_name) {
require(__DIR__ . "/view/$_name");
}
exit;
}
// CSRFトークン関連
function set_csrf_token() {
if (empty($_SESSION['csrf_token'])) {
$_SESSION["csrf_token"] = bin2hex(random_bytes(32));
}
}
function get_csrf_token() {
if (!REQUIRE_COOKIE && !isset($_SESSION['user'])) {
$date = date('YmdH');
return $date . get_fp();
}
return $_SESSION['csrf_token'] ?? null;
}
function get_csrf_token_2($force_cookie = false) {
if (!REQUIRE_COOKIE && !isset($_SESSION['user'])) {
$date = date('YmdH', strtotime('-1 hour'));
return $date . get_fp();
}
return $_SESSION['csrf_token'] ?? null;
}
function get_csrf_token_hashed($prefix = '', $token = null) {
if ($token === null) { $token = get_csrf_token(); }
if ($token === null) { return null; }
return md5($prefix . $token);
}
function check_csrf_token() {
$hashed = get_csrf_token_hashed();
$hashed_2 = get_csrf_token_hashed('', get_csrf_token_2());
if ($hashed === null || $hashed_2 === null) { return ['CSRF トークンが不正。要再試行。']; }
$token_key = get_csrf_token_hashed('csrf_token');
$csrf_token = $_POST[$token_key] ?? '';
if ($csrf_token !== $hashed && $csrf_token !== $hashed_2) { return ['CSRF トークンが不正。要再試行。']; }
return [];
}
function output_csrf_token_hidden() {
$hashed = get_csrf_token_hashed();
if ($hashed === null) { return ''; }
$token_key = get_csrf_token_hashed('csrf_token');
return '<input type="hidden" name="' . htmlspecialchars($token_key) . '" value="' . $hashed . '">';
}
// 文字列関連
function post_default_title($id) {
return '無題#' . mb_substr($id, 0, 7);
}
function anchor_to_link($s, $thread_id) {
return preg_replace(
'/&gt;&gt;([1-9]+[0-9]{0,10})/',
'<a href="' . sitebase('post/?id=') . $thread_id . '&amp;res=\1">&gt;&gt;\1</a>',
$s
);
}
function url_to_link($s) {
return preg_replace(
'/((http|https):\/\/[\w-]+(\.[\w-]+)+([\w.,@?^=%&amp;:\/~+#-]*[\w@?^=%&amp;\/~+#-])?)/',
'<a href="\1" rel="noopener noreferrer">\1</a>',
$s
);
}
function mbtrim($s) {
return preg_replace('/^\s+|\s+$/u', '', $s);
}
function twochan_trip($tripkey) {
// twochan_trip('atomikka') -> '◆.../5Betyws'
// Thanks: https://refirio.org/view/62
// Test data: https://trip-table.kokage.cc/sample01.php
$tripkey = mb_convert_encoding($tripkey, 'sjis-win');
$salt = substr($tripkey . 'H.', 1, 2);
$salt = preg_replace('/[^\.-z]/', '.', $salt);
$salt = strtr($salt, ':;<=>?@[\\]^_`', 'ABCDEFGabcdef');
$trip = crypt($tripkey, $salt);
$trip = substr($trip, -10);
return '◆' . $trip;
}
function parse_key_value($s, $key_list) {
$result = [];
$lines = explode(PHP_EOL, $s);
foreach ($lines as $line) {
foreach ($key_list as $key) {
if (strpos($line, "{$key}=") === 0) {
$result[$key] = explode('=', $line, 2)[1] ?? null;
}
}
unset($key);
}
unset($lines, $line);
return $result;
}
// ファイル関連
function mkdir_p($path, $permission = 0700) {
if (file_exists($path)) { return true; }
return mkdir($path, $permission);
}
function get_image_type($s) {
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$type = finfo_buffer($finfo, $s);
if (isset($type) && in_array($type, ACCEPT_IMAGE_TYPE)) {
return $type;
}
return null;
}
function sitebase($path = '') {
return SITEBASE . $path;
}
function get_style_css() {
if (THEME === null || THEME === '') { return sitebase('style.css'); }
return sitebase('theme/' . THEME);
}
// 制限・権限
function is_logged_in() {
return isset($_SESSION['user']);
}
function can_post() {
if (!post_limited()) { return false; }
if (!ENABLE_GUEST && !is_logged_in()) { return false; }
return true;
}
function post_limited() {
return ENABLE_POST && (count_post_today() < POST_LIMIT_PER_DAY) && (count_post() < POST_LIMIT);
}
function can_regist() {
return ENABLE_REGISTER;
}