Browse Source

Merge pull request 'KEKEC_BBS_DEV-001' (#5) from KEKEC_BBS_DEV-001 into main

Reviewed-on: #5
main
みてるぞ 10 months ago
parent
commit
f0e267507e
18 changed files with 624 additions and 484 deletions
  1. +2
    -2
      .gitignore
  2. BIN
      assets/kusobbs.gif
  3. +0
    -0
      assets/music.mp3
  4. +12
    -0
      database.example.php
  5. +311
    -0
      forms/index.frm.php
  6. +24
    -363
      index.php
  7. +10
    -0
      migrate.php
  8. +2
    -0
      migrations/2023_09_01_011340_create_threads_table.sql
  9. +2
    -0
      migrations/2023_09_01_012000_create_responses_table.sql
  10. +9
    -3
      modules/backup.php
  11. +2
    -2
      modules/delete.php
  12. +2
    -2
      modules/make_thread.php
  13. +2
    -2
      modules/upload.php
  14. +0
    -0
      scripts/colour-pad.js
  15. +3
    -3
      scripts/paint.js
  16. +3
    -3
      scripts/script.js
  17. +0
    -104
      style.css
  18. +240
    -0
      styles/style.css

+ 2
- 2
.gitignore View File

@@ -1,4 +1,4 @@
/image
/draft
/images
/drafts
/database.php


BIN
assets/kusobbs.gif View File

Before After
Width: 1990  |  Height: 390  |  Size: 805 KiB

music.mp3 → assets/music.mp3 View File


+ 12
- 0
database.example.php View File

@@ -0,0 +1,12 @@
<?php

function
set_mysql ($db)
{
$url = 'localhost';
$user = 'root';
$pass = '';

return new mysqli ($url, $user, $pass, $db);
}


+ 311
- 0
forms/index.frm.php View File

@@ -0,0 +1,311 @@
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8" />
<meta name="robots" content="noindex" />
<title><?= ($title == '') ? '' : ($title . ' - ') ?>キケッツチャンネル お絵描き掲示板</title>
<link rel="stylesheet" href="https://jpafonts.osdn.jp/webfonts/jpafonts.css" />
<link rel="stylesheet" type="text/css" href="./styles/style.css" />
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.15.4/css/all.css" />
<script defer src="https://use.fontawesome.com/releases/v5.15.4/js/all.js"></script>
<script src="./scripts/colour-pad.js"></script>
</head>

<body>
<!-- <div style="font-size: 500%">
メンテ中
</div> -->

<div id="modal" class="modal">
<div class="modal-content">
<h3>Canvas のサイズを変更</h3>

<form>
<div style="margin-bottom: 16px">
<div>
<label for="width">幅:</label>
<input type="number" id="change-width" name="width" value="480" min="32" max="640" />
<label>(32 〜 640)</label>
</div>

<div>
<label for="height">高さ:</label>
<input type="number" id="change-height" name="height" value="480" min="24" max="480" />
<label>(24 〜 480)</label>
</div>
</div>

<button type="button" onclick="closeModal ()">取消</button>
<button type="button" onclick="applyResolution ()">適用</button>
</form>
</div>
</div>

<h1><a href="."><img src="/assets/kusobbs.gif" alt="クソ掲示板" style="width: 398px" /></a></h1>
<div style="text-align: center"><a href="#" onclick="PauseMusic ()" id="mute">&emsp;</a></div>

<?php if ($thread == -1): ?>
<form action="./modules/make_thread.php" method="POST">
スレ名:<input type="text" name="thread-name" /><br />
スレ内容:<textarea name="thread-explain"></textarea><br />
<input type="submit" value="スレ立て" />
</form>

<?php if ($result = $mysqli -> query ("SELECT * FROM threads WHERE id <> 1 ORDER BY latest DESC")): ?>
<?php while ($row = $result -> fetch_assoc ()): ?>
<table width="90%">
<thead>
<tr><td class="header"><a href="?thread=<?= $row['id'] ?>"><?= $row['title'] ?></a>&emsp;更新:1<?= $row['latest'] ?>&emsp;<?= $row['length'] ?> レス</td></tr>
</thead>

<?php if ($row['explain'] != '<p></p>'): ?>
<tbody>
<tr><td><?= $row['explain'] ?></td></tr>
</tbody>
<?php endif ?>
</table>
<?php endwhile ?>
<?php endif ?>

<?php else: ?>
<table width="90%">
<thead>
<tr><td class="header"><?= $title ?></td></tr>
</thead>

<?php if ($explain != '<p></p>'): ?>
<tbody>
<tr><td><?= $explain ?></td></tr>
</tbody>
<?php endif ?>
</table>

<form id="message-form">
<label>名前:</label><input type="text" id="user-name" name="name" /><br />
<label>削除用パスワード:</label><input type="password" id="password" name="password" />
<!-- <textarea id="message" name="message"></textarea> -->
</form>

<div id="paint">
<div style="display: flex; justify-content: center">
<div class="button-area" style="margin-right: 64px">
<button id="new">新規作成</button>
<button id="send">送信</button>
<button id="save">ダウンロード</button>
<button id="change-size">サイズ変更</button>
</div>

<div class="button-area" style="vertical-align: middle">
<button id="undo">←</button>
<button id="redo">→</button>
</div>
</div>

<div style="display: flex; width: max-content; flex-direction: column">
<div class="radio">
<form id="mode">
<label>モード:</label>
<label><input type="radio" name="mode" value="pen" id="pen" checked />ペン</label>
<label><input type="radio" name="mode" value="rubber" id="rubber" />消しゴム</label>
<label><input type="radio" name="mode" value="bucket" id="bucket" />塗りつぶし</label>
</form>
</div>

<div class="radio">
<label>取込み:</label>
<input id="load" type="file" onChange="LoadFile (this.files)" />
</div>

<div class="radio">
<form id="colour">
<label>色:</label>
<!-- <input type="radio" name="colour" value="black" checked="checked" />黒
<input type="radio" name="colour" value="blue" />ブルー
<input type="radio" name="colour" value="red" />赤
<input type="radio" name="colour" value="magenta" />マジェンタ
<input type="radio" name="colour" value="lime" />ライム
<input type="radio" name="colour" value="cyan" />青
<input type="radio" name="colour" value="yellow" />イェロウ
<input type="radio" name="colour" value="white" />白 -->
<button id="colour-picker" type="button" onclick="cmanCP_JS_open(this)" cmanCPat="def_color:cns=#000000,rc_form:RGBA,rc_func:changeColour">選択</button>
<label id="irorororo">黒</label>
</form>
</div>

<div class="radio">
<form id="size">
<label>太さ:</label>
<label><input type="radio" name="size" value="1" />1</label>
<label><input type="radio" name="size" value="2" />2</label>
<label><input type="radio" name="size" value="3" checked="checked" />3</label>
<label><input type="radio" name="size" value="5" />5</label>
<label><input type="radio" name="size" value="7" />7</label>
<label><input type="radio" name="size" value="10" />10</label>
<label><input type="radio" name="size" value="15" />15</label>
<!-- <input type="range" name="size" min="1" max="57" value="3" /> -->
<label><input type="radio" name="size" value="0" />指定:
<input style="width: 2em" type="number" name="size" id="size-free" value="57" /></label>
</form>
</div>

<div class="radio">
<form id="layer">
<label>レイア:</label>
<label><input onclick="reDraw ()" type="radio" name="layer" value="0" checked="checked" />基底</label>
<label><input onclick="reDraw ()" type="radio" name="layer" value="1" />1</label>
<label><input onclick="reDraw ()" type="radio" name="layer" value="2" />2</label>
<button type="button" name="del">削除</button>
<button type="button" name="down">下へ</button>
<button type="button" name="up">上へ</button>
<button type="button" name="add">追加</button>
<br />
<label><input onclick="reDraw ()" type="checkbox" name="sep" />レイアを分けて表示</label>
</form>
</div>
</div>

<div class="canvas-area" id="canvas-area">
<canvas id="canvas" width="480" height="480"></canvas>
<!-- <canvas id="canvas1" width="480" height="480"></canvas> -->
<!-- <canvas id="canvas2" width="480" height="480"></canvas> -->
</div>
</div>

<form name="sort">
<label>
並べ替え:

<select id="sort" style="font-size: 24px">
<option value="time-desc"<?= ($sort == 'td') ? ' selected="selected"' : '' ?>>投稿が新しい順</option>
<option value="evaluate-good"<?= ($sort == 'eg') ? ' selected="selected"' : '' ?>>評価が高い順</option>
<option value="time-asc"<?= ($sort == 'ta') ? ' selected="selected"' : '' ?>>投稿が古い順</option>
<option value="evaluate-bad"<?= ($sort == 'eb') ? ' selected="selected"' : '' ?>>評価が低い順</option>
</select>
</label>
</form>

<div id="bbs">
<?php
if ($result = $mysqli -> query ("
SELECT
response_id as id, name, message, date, image, held, deleted, pass, good, bad, good - bad as evaluate
FROM
responses
WHERE
thread_id = $thread
ORDER BY
" . (($sort == 'td')
? 'id DESC'
: (($sort == 'eg')
? 'evaluate DESC, id DESC'
: (($sort == 'ta')
? 'id ASC'
: (($sort == 'eb')
? 'evaluate ASC, id DESC'
: 'id DESC')))))):
?>
<?php while ($row = $result -> fetch_assoc ()): ?>
<table width="90%" id="<?= $row['id'] ?>">
<thead>
<tr>
<td class="header">
<div style="margin: 0 8px">
<div style="float: left"><?= $row['id'] ?>:
<?= (($row['name'] == '')
? '名なしさん'
: $row['name']) ?>
</div>

<div style="text-align: right">
1<?= date ('Y/m/d H:i:s', strtotime ($row['date'])) ?>
</div>
</div>

<div style="display: grid;
grid-template-columns: auto <?= ($row['good'] + $row['bad'] == 0) ? '.48fr' : ((.96 * $row['bad'] / ($row['good'] + $row['bad'])) . 'fr') ?> <?= ($row['good'] + $row['bad'] == 0) ? '.48fr' : ((.96 * $row['good'] / ($row['good'] + $row['bad'])) . 'fr') ?> auto;
align-items: center;
margin-top: 8px;
margin-left: auto;
margin-right: auto;
width: 90%;
font-size: 80%">
<div style="grid-columns: 1; text-align: left;">
<a style="color: blue; white-space: nowrap" title="低評価"
href="?thread=<?= $thread ?>&sort=<?= $sort ?>&evaluate=bad&id=<?= $row['id'] ?>#<?= $row['id'] ?>">
<i class="fas fa-thumbs-down"></i>&thinsp;<?= $row['bad'] ?>
</a>
</div>

<div style="grid-columns: 2;
background-color: blue;
text-align: center;
height: 40%">
&nbsp;
</div>

<div style="grid-columns: 3;
background-color: red;
text-align: center;
height: 40%">
&nbsp;
</div>

<div style="grid-columns: 4; text-align: right">
<a style="color: red" title="高評価" href="?thread=<?= $thread ?>&sort=<?= $sort ?>&evaluate=good&id=<?= $row['id'] ?>#<?= $row['id'] ?>">
<?= $row['good'] ?>&thinsp;<i class="fas fa-thumbs-up"></i>
</a>
</div>
</div>
</td>
</tr>
</thead>

<tbody>
<?php if ($row['deleted']): ?>
<tr><td><p>削除されました.</p></td></tr>
<?php elseif ($row['held']): ?>
<tr><td><p>確認中です.</p></td></tr>
<?php else: ?>
<tr><td class="illust" style="display: grid; grid-template-columns: .375fr auto .375fr; align-items: end"><div style="grid-columns: 1"></div><div style="grid-columns: 2; text-align: center"><img style="border: solid 1px"src="<?= $dir . $row['image'] ?>" /></div><div style="grid-columns: 3; justify-self: end; margin-right: 8px; margin-bottom: 8px; font-size: 80%"><a href="#del" onclick="deletePost (<?= $row['id'] ?>)">削除</a></div></td></tr>
<?php endif ?>
</tbody>
</table>
<?php endwhile ?>

<?php
// MySQL を閉ぢる.
$result -> close ();
endif;
?>
</div>

<h3 id="del">レス削除</h3>
削除したいレス番号と削除用パスワードを入力して &ldquo;削除&rdquo; を押してください.<br />
<label>レス番号:</label><input type="text" id="del-id" /><br />
<label>削除用パスワード:</label><input type="password" id="del-pass" /><br />
<button id="delete" onclick="deletePostReally ()">削除</button>
<?php endif ?>

<hr />

<footer>
<div class="attention">
このサイトでは,<a href="https://moji.or.jp/ipafont/license/" target="_blank">IPA フォントライセンス v1.0</a> で公開されてゐる <a href="https://jpafonts.osdn.jp/" target="_blank">JPA フォント</a>を使用してゐます.
</div>

<div class="copyright">
&copy; このペィジへの投稿は,すべて,パブリック・ドメインとします.
</div>
</footer>

<canvas style="display: none" width="1" height="1" id="work"></canvas>
<canvas style="display: none" width="480" height="480" id="canvas-perfect"></canvas>

<script type="text/javascript" src="./scripts/script.js"></script>

<?php if ($thread != -1): ?>
<script type="text/javascript" src="./scripts/paint.js"></script>
<?php endif ?>
</body>
</html>


+ 24
- 363
index.php View File

@@ -1,31 +1,29 @@
<?php
require "${_SERVER['DOCUMENT_ROOT']}/database.php";

require_once "${_SERVER['DOCUMENT_ROOT']}/database.php";

if (isset ($_GET['page'])):
$page = $_GET['page'];
else:
$page = 0;
endif;
if (isset ($_GET['page']))
$page = $_GET['page'];
else
$page = 0;

if (isset ($_GET['thread'])):
$thread = $_GET['thread'];
else:
$thread = -1;
endif;
if (isset ($_GET['thread']))
$thread = $_GET['thread'];
else
$thread = -1;

if (isset ($_GET['sort'])):
if (isset ($_GET['sort']))
{
$sort = $_GET['sort'];

if (!(in_array ($sort, array ('td', 'eg', 'ta', 'eb')))):
$sort = 'td';
endif;
else:
$sort = 'td';
endif;
if (!(in_array ($sort, array ('td', 'eg', 'ta', 'eb'))))
$sort = 'td';
}
else
$sort = 'td';

// 画像のディレクトリを開く.
$dir = 'image/';
$dir = '/images/';
$handle = opendir ($dir);

// MySQL 宣言
@@ -33,18 +31,20 @@ $mysqli = set_mysql ('miteruzo_bbs');

$mysqli -> set_charset ('utf8');

if ($result = $mysqli -> query ("SELECT * FROM threads WHERE id = $thread")):
if ($result = $mysqli -> query ("SELECT * FROM threads WHERE id = $thread"))
{
$row = $result -> fetch_assoc ();

$title = $row['title'];
$explain = $row['explain'];

$result -> close ();
endif;
}

if (isset ($_GET['id'])
&& isset ($_GET['evaluate'])
&& (($_GET['evaluate'] == 'good') || ($_GET['evaluate'] == 'bad'))):
&& (($_GET['evaluate'] == 'good') || ($_GET['evaluate'] == 'bad')))
{
$mysqli -> query ("
UPDATE
responses
@@ -54,346 +54,7 @@ if (isset ($_GET['id'])
(thread_id = $thread) AND (response_id = {$_GET['id']})");

header ("Location: ./?thread=$thread&sort=$sort");
endif;
?>
<!DOCTYPE html>
}

<html lang="ja">
<head>
<meta charset="UTF-8" />
<meta name="robots" content="noindex" />
<title><?= ($title == '') ? '' : ($title . ' - ') ?>キケッツチャンネル お絵描き掲示板</title>
<link rel="stylesheet" href="https://jpafonts.osdn.jp/webfonts/jpafonts.css" />
<link rel="stylesheet" type="text/css" href="/style.css" />
<link rel="stylesheet" type="text/css" href="style.css" />
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.15.4/css/all.css" />
<script defer src="https://use.fontawesome.com/releases/v5.15.4/js/all.js"></script>
<script src="modules/colour-pad.js"></script>
</head>

<body>
<!-- <div style="font-size: 500%">
メンテ中
</div> -->

<div id="modal" class="modal">
<div class="modal-content">
<h3>Canvas のサイズを変更</h3>

<form>
<div style="margin-bottom: 16px">
<div>
<label for="width">幅:</label>
<input type="number" id="change-width" name="width" value="480" min="32" max="640" />
<label>(32 〜 640)</label>
</div>

<div>
<label for="height">高さ:</label>
<input type="number" id="change-height" name="height" value="480" min="24" max="480" />
<label>(24 〜 480)</label>
</div>
</div>

<button type="button" onclick="closeModal ()">取消</button>
<button type="button" onclick="applyResolution ()">適用</button>
</form>
</div>
</div>

<h1><a href="."><img src="/img/kusobbs.gif" alt="クソ掲示板" style="width: 398px" /></a></h1>
<div style="text-align: center"><a href="#" onclick="PauseMusic ()" id="mute">&emsp;</a></div>

<?php
if ($thread == -1):
?>
<form action="make_thread.php" method="POST">
スレ名:<input type="text" name="thread-name" /><br />
スレ内容:<textarea name="thread-explain"></textarea><br />
<input type="submit" value="スレ立て" />
</form>
<?php
if ($result = $mysqli -> query ("SELECT * FROM threads WHERE id <> 1 ORDER BY latest DESC")):
while ($row = $result -> fetch_assoc ()):
?>
<table width="90%">
<thead>
<tr><td class="header"><a href="?thread=<?= $row['id'] ?>"><?= $row['title'] ?></a>&emsp;更新:1<?= $row['latest'] ?>&emsp;<?= $row['length'] ?> レス</td></tr>
</thead>

<?php
if ($row['explain'] != '<p></p>'):
?>

<tbody>
<tr><td><?= $row['explain'] ?></td></tr>
</tbody>
</table>
<?php
endif; // end of ($row['explain'] != '<p></p>')
endwhile; // end of ($row = $result -> fetch_assoc ())
endif; // end of ($result = $mysqli -> query ("SELECT * FROM threads ORDER BY latest DESC"))
else: // $thread != -1
?>

<table width="90%">
<thead>
<tr><td class="header"><?= $title ?></td></tr>
</thead>

<?php
if ($explain != '<p></p>'):
?>
<tbody>
<tr><td><?= $explain ?></td></tr>
</tbody>

<?php
endif;
?>
</table>

<form id="message-form">
<label>名前:</label><input type="text" id="user-name" name="name" /><br />
<label>削除用パスワード:</label><input type="password" id="password" name="password" />
<!-- <textarea id="message" name="message"></textarea> -->
</form>

<div id="paint">
<div style="display: flex; justify-content: center">
<div class="button-area" style="margin-right: 64px">
<button id="new">新規作成</button>
<button id="send">送信</button>
<button id="save">ダウンロード</button>
<button id="change-size">サイズ変更</button>
</div>

<div class="button-area" style="vertical-align: middle">
<button id="undo">←</button>
<button id="redo">→</button>
</div>
</div>

<div style="display: flex; width: max-content; flex-direction: column">
<div class="radio">
<form id="mode">
<label>モード:</label>
<label><input type="radio" name="mode" value="pen" id="pen" checked />ペン</label>
<label><input type="radio" name="mode" value="rubber" id="rubber" />消しゴム</label>
<label><input type="radio" name="mode" value="bucket" id="bucket" />塗りつぶし</label>
</form>
</div>

<div class="radio">
<label>取込み:</label>
<input id="load" type="file" onChange="LoadFile (this.files)" />
</div>

<div class="radio">
<form id="colour">
<label>色:</label>
<!-- <input type="radio" name="colour" value="black" checked="checked" />黒
<input type="radio" name="colour" value="blue" />ブルー
<input type="radio" name="colour" value="red" />赤
<input type="radio" name="colour" value="magenta" />マジェンタ
<input type="radio" name="colour" value="lime" />ライム
<input type="radio" name="colour" value="cyan" />青
<input type="radio" name="colour" value="yellow" />イェロウ
<input type="radio" name="colour" value="white" />白 -->
<button id="colour-picker" type="button" onclick="cmanCP_JS_open(this)" cmanCPat="def_color:cns=#000000,rc_form:RGBA,rc_func:changeColour">選択</button>
<label id="irorororo">黒</label>
</form>
</div>

<div class="radio">
<form id="size">
<label>太さ:</label>
<label><input type="radio" name="size" value="1" />1</label>
<label><input type="radio" name="size" value="2" />2</label>
<label><input type="radio" name="size" value="3" checked="checked" />3</label>
<label><input type="radio" name="size" value="5" />5</label>
<label><input type="radio" name="size" value="7" />7</label>
<label><input type="radio" name="size" value="10" />10</label>
<label><input type="radio" name="size" value="15" />15</label>
<!-- <input type="range" name="size" min="1" max="57" value="3" /> -->
<label><input type="radio" name="size" value="0" />指定:
<input style="width: 2em" type="number" name="size" id="size-free" value="57" /></label>
</form>
</div>

<div class="radio">
<form id="layer">
<label>レイア:</label>
<label><input onclick="reDraw ()" type="radio" name="layer" value="0" checked="checked" />基底</label>
<label><input onclick="reDraw ()" type="radio" name="layer" value="1" />1</label>
<label><input onclick="reDraw ()" type="radio" name="layer" value="2" />2</label>
<button type="button" name="del">削除</button>
<button type="button" name="down">下へ</button>
<button type="button" name="up">上へ</button>
<button type="button" name="add">追加</button>
<br />
<label><input onclick="reDraw ()" type="checkbox" name="sep" />レイアを分けて表示</label>
</form>
</div>
</div>

<div class="canvas-area" id="canvas-area">
<canvas id="canvas" width="480" height="480"></canvas>
<!-- <canvas id="canvas1" width="480" height="480"></canvas> -->
<!-- <canvas id="canvas2" width="480" height="480"></canvas> -->
</div>
</div>

<form name="sort">
<label>
並べ替え:

<select id="sort" style="font-size: 24px">
<option value="time-desc"<?= ($sort == 'td') ? ' selected="selected"' : '' ?>>投稿が新しい順</option>
<option value="evaluate-good"<?= ($sort == 'eg') ? ' selected="selected"' : '' ?>>評価が高い順</option>
<option value="time-asc"<?= ($sort == 'ta') ? ' selected="selected"' : '' ?>>投稿が古い順</option>
<option value="evaluate-bad"<?= ($sort == 'eb') ? ' selected="selected"' : '' ?>>評価が低い順</option>
</select>
</label>
</form>

<div id="bbs">
<?php
// スレ内のレスをすべて取得
if ($result = $mysqli -> query ("
SELECT
response_id as id, name, message, date, image, held, deleted, pass, good, bad, good - bad as evaluate
FROM
responses
WHERE
thread_id = $thread
ORDER BY
" . (($sort == 'td')
? 'id DESC'
: (($sort == 'eg')
? 'evaluate DESC, id DESC'
: (($sort == 'ta')
? 'id ASC'
: (($sort == 'eb')
? 'evaluate ASC, id DESC'
: 'id DESC')))))):
while ($row = $result -> fetch_assoc ()):
?>
<table width="90%" id="<?= $row['id'] ?>">
<thead>
<tr>
<td class="header">
<div style="margin: 0 8px">
<div style="float: left"><?= $row['id'] ?>:
<?= (($row['name'] == '')
? '名なしさん'
: $row['name']) ?>
</div>

<div style="text-align: right">
1<?= date ('Y/m/d H:i:s', strtotime ($row['date'])) ?>
</div>
</div>

<div style="display: grid;
grid-template-columns: auto <?= ($row['good'] + $row['bad'] == 0) ? '.48fr' : ((.96 * $row['bad'] / ($row['good'] + $row['bad'])) . 'fr') ?> <?= ($row['good'] + $row['bad'] == 0) ? '.48fr' : ((.96 * $row['good'] / ($row['good'] + $row['bad'])) . 'fr') ?> auto;
align-items: center;
margin-top: 8px;
margin-left: auto;
margin-right: auto;
width: 90%;
font-size: 80%">
<div style="grid-columns: 1; text-align: left;">
<a style="color: blue; white-space: nowrap" title="低評価"
href="?thread=<?= $thread ?>&sort=<?= $sort ?>&evaluate=bad&id=<?= $row['id'] ?>#<?= $row['id'] ?>">
<i class="fas fa-thumbs-down"></i>&thinsp;<?= $row['bad'] ?>
</a>
</div>

<div style="grid-columns: 2;
background-color: blue;
text-align: center;
height: 40%">
&nbsp;
</div>

<div style="grid-columns: 3;
background-color: red;
text-align: center;
height: 40%">
&nbsp;
</div>

<div style="grid-columns: 4; text-align: right">
<a style="color: red" title="高評価" href="?thread=<?= $thread ?>&sort=<?= $sort ?>&evaluate=good&id=<?= $row['id'] ?>#<?= $row['id'] ?>">
<?= $row['good'] ?>&thinsp;<i class="fas fa-thumbs-up"></i>
</a>
</div>
</div>
</td>
</tr>
</thead>

<tbody>
<?php
// 特殊なメッシジ
if ($row['deleted']): // 削除された場合
?>
<tr><td><p>削除されました.</p></td></tr>
<?php
elseif ($row['held']): // 保留中の場合
?>
<tr><td><p>確認中です.</p></td></tr>
<?php
else:
?>
<tr><td class="illust" style="display: grid; grid-template-columns: .375fr auto .375fr; align-items: end"><div style="grid-columns: 1"></div><div style="grid-columns: 2; text-align: center"><img style="border: solid 1px"src="<?= $dir . $row['image'] ?>" /></div><div style="grid-columns: 3; justify-self: end; margin-right: 8px; margin-bottom: 8px; font-size: 80%"><a href="#del" onclick="deletePost (<?= $row['id'] ?>)">削除</a></div></td></tr>
<?php
endif;
?>
</tbody>
</table>
<?php
endwhile;

// MySQL を閉ぢる.
$result -> close ();
endif;
?>
</div>

<h3 id="del">レス削除</h3>
削除したいレス番号と削除用パスワードを入力して &ldquo;削除&rdquo; を押してください.<br />
<label>レス番号:</label><input type="text" id="del-id" /><br />
<label>削除用パスワード:</label><input type="password" id="del-pass" /><br />
<button id="delete" onclick="deletePostReally ()">削除</button>
<?php
endif;
?>

<hr />

<footer>
<div class="attention">
このサイトでは,<a href="https://moji.or.jp/ipafont/license/" target="_blank">IPA フォントライセンス v1.0</a> で公開されてゐる <a href="https://jpafonts.osdn.jp/" target="_blank">JPA フォント</a>を使用してゐます.
</div>

<div class="copyright">
&copy; このペィジへの投稿は,すべて,パブリック・ドメインとします.
</div>
</footer>

<canvas style="display: none" width="1" height="1" id="work"></canvas>
<canvas style="display: none" width="480" height="480" id="canvas-perfect"></canvas>

<script type="text/javascript" src="script.js"></script>
<?php
if ($thread != -1):
?>
<script type="text/javascript" src="paint.js"></script>
<?php
endif;
?>
</body>
</html>
require_once './forms/index.frm.php';


+ 10
- 0
migrate.php View File

@@ -0,0 +1,10 @@
<?php

require_once './db_connection.php';


$files = glob ('./migrations/*.sql');

foreach ($files as $file)
$__db_connection -> query (file_get_contents ($file));


+ 2
- 0
migrations/2023_09_01_011340_create_threads_table.sql View File

@@ -0,0 +1,2 @@
CREATE TABLE `miteruzo_bbs`.`threads` ( `id` INT NOT NULL AUTO_INCREMENT , `title` VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL , `explain` MEDIUMTEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL , `latest` DATETIME NOT NULL , `length` INT NOT NULL DEFAULT '0' , PRIMARY KEY (`id`)) ENGINE = InnoDB CHARSET=utf8mb4 COLLATE utf8mb4_unicode_ci;


+ 2
- 0
migrations/2023_09_01_012000_create_responses_table.sql View File

@@ -0,0 +1,2 @@
CREATE TABLE `miteruzo_bbs`.`responses` ( `thread_id` INT NOT NULL , `response_id` INT NOT NULL , `name` VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '名なしさん' , `message` MEDIUMTEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL , `date` DATETIME NOT NULL , `image` VARCHAR(31) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL , `held` TINYINT NOT NULL DEFAULT '0' , `deleted` TINYINT NOT NULL DEFAULT '0' , `pass` VARCHAR(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL , `good` INT NOT NULL DEFAULT '0' , `bad` INT NOT NULL DEFAULT '0' , PRIMARY KEY (`thread_id`, `response_id`)) ENGINE = InnoDB CHARSET=utf8mb4 COLLATE utf8mb4_unicode_ci;


backup.php → modules/backup.php View File

@@ -1,17 +1,19 @@
<?php
define ('SAVE_DIR', 'draft/');
define ('SAVE_DIR', "${_SERVER['DOCUMENT_ROOT']}/drafts/");

$json = getParamJSON ();

if (!(isset ($json['data'])))
{
sendResult (false, 'Empty query Parameter: data');

exit (1);
}

if (!(preg_match ('/^data:image\/png;base64,/', $json['data'])))
{
sendResult (false, 'Not Allow data type: data');

exit (1);
}

@@ -27,7 +29,8 @@ setcookie ('backup', $file, time () + 60 * 60 * 24 * 30);


function
getParamJSON ()
getParamJSON ():
array
{
$buff = file_get_contents ('php://input');
$json = json_decode ($buff, true);
@@ -36,7 +39,10 @@ getParamJSON ()
}

function
sendResult ($status, $data)
sendResult (
$status,
$data):
string
{
header ('Access-Control-Allow-Origin: *');
header ('Access-Control-Allow-Headers: *');

delete.php → modules/delete.php View File

@@ -28,11 +28,11 @@ if ($result = $mysqli -> query ("
WHERE
(thread_id = $thread) AND (response_id = $id)");

echo "消しましたぁ!!<br /><br /><img style='border: solid 1px' src='image/{$row['image']}' />";
echo "消しましたぁ!!<br /><br /><img style='border: solid 1px' src='/images/{$row['image']}' />";
else:
echo '残念.<br />削除用パスワードが違います.';
endif;

echo "<br /><br />5 秒後に元のページに戻ります.<br /><br /><a href='./?thread=$thread#$id'>戻らない場合はこちら</a><script>setTimeout (function () {window.location.href = `./?thread=$thread#$id`}, 5000)</script>";
echo "<br /><br />5 秒後に元のページに戻ります.<br /><br /><a href='/?thread=$thread#$id'>戻らない場合はこちら</a><script>setTimeout (function () {window.location.href = `/?thread=$thread#$id`}, 5000)</script>";
endif;


make_thread.php → modules/make_thread.php View File

@@ -17,7 +17,7 @@ if (!(empty ($_POST['thread-name'])))

$result -> close ();

$sql = "INSERT INTO threads (id, title, `explain`, latest, length) VALUES ($current, '{$_POST['thread-name']}', '$explain', '" . date ('Y-m-d H:i:s') . "', 0)";
$sql = "INSERT INTO threads (title, `explain`, latest, length) VALUES ('{$_POST['thread-name']}', '$explain', '" . date ('Y-m-d H:i:s') . "', 0)";
$mysqli -> query ($sql);
/* $sql = "CREATE TABLE `miteruzo_bbs`.`thread_$current` (
`id` INT( 11 ) NOT NULL AUTO_INCREMENT PRIMARY KEY COMMENT 'レス番',
@@ -37,5 +37,5 @@ if (!(empty ($_POST['thread-name'])))
$mysqli -> close ();
}

header ("location: ./?thread=$current");
header ("location: ../?thread=$current");


upload.php → modules/upload.php View File

@@ -2,10 +2,10 @@
require "${_SERVER['DOCUMENT_ROOT']}/database.php";


define ('SAVE_DIR', 'image/'); // 保存ディレクトリ定義
define ('SAVE_DIR', "${_SERVER['DOCUMENT_ROOT']}/images/"); // 保存ディレクトリ定義

$thread = $_GET['thread'];
file_put_contents ('log.txt', $thread);
// file_put_contents ('log.txt', $thread);

$json = getParamJSON (); // JSON パラメタ


modules/colour-pad.js → scripts/colour-pad.js View File


paint.js → scripts/paint.js View File

@@ -219,11 +219,11 @@ SendToServer (backup)
mode: 'cors'};

if (backup)
await SendServer (`backup.php?id=${uniqId}`, param);
await SendServer (`/modules/backup.php?id=${uniqId}`, param);
else
{
// SendServer (`upload.php?name=${userName.value}&pass=${password.value}&msg=${message.value}`, param);
await SendServer (`upload.php${window.location.search}&name=${userName.value}&pass=${password.value}&held=${held ? 1 : 0}&uniqid=${uniqId}`, param);
await SendServer (`/modules/upload.php${window.location.search}&name=${userName.value}&pass=${password.value}&held=${held ? 1 : 0}&uniqid=${uniqId}`, param);
}
}

@@ -872,7 +872,7 @@ deletePostReally ()
{
const searchParams = new URLSearchParams (window.location.search);

window.location.href = `./delete.php?thread=${searchParams.get (
window.location.href = `./modules/delete.php?thread=${searchParams.get (
'thread')}&id=${delId.value}&pass=${delPass.value}`;
}
else

script.js → scripts/script.js View File

@@ -1,6 +1,6 @@
const music = new Audio ('music.mp3'); // BGM
let playing = false; // 再生フラグ
let nowPlay = true; // 再生すべきかどぅか
const music = new Audio ('./assets/music.mp3'); // BGM
let playing = false; // 再生フラグ
let nowPlay = true; // 再生すべきかどぅか

document.getElementById ('sort').addEventListener ('change', sortChange);


+ 0
- 104
style.css View File

@@ -1,104 +0,0 @@
body
{
background-color: aquamarine;
}

table
{
margin: 24px auto 40px;
}

td
{
padding: 8px;
}

table, td
{
border: solid 1px;
background-color: white;
}

#paint
{
margin-bottom: 64px;
}

#paint > div
{
margin: 24px auto;
}

h1, .illust
{
text-align: center;
}

.radio
{
/* width: 704px; */
/* display: inline-block; */
vertical-align: middle;
line-height: 1.5em;
/* margin: auto; */
}

.button-area, .canvas-area
{
text-align: center;
}

.canvas-area
{
width: 480px;
height: 480px;
max-width: 100%;
position: relative;
padding: 0;
box-sizing: content-box;
}

.canvas-area:before
{
content: "";
display: block;
padding-top: 100%;
}

.canvas-area > canvas
{
position: absolute;
left: 0;
top: 0;
border: 1px solid;
max-width: 100%;
box-sizing: content-box;
padding: 0;
margin: 0;
}

.modal {
display: none;
position: fixed;
z-index: 1;
left: 0;
top: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.4);
}

.modal-content {
background-color: #fff;
margin: 15% auto;
padding: 20px;
border: 1px solid #888;
width: 400px;
text-align: center;
}

@media only screen and (max-width: 600px) {
.modal-content {
width: 70%;
}
}

+ 240
- 0
styles/style.css View File

@@ -0,0 +1,240 @@
html
{
font-size: 24px;
font-family: "Helvetica Neue", "Helvetica", "Segoe UI", "Arial",
"JPAGothic", "IPAGothic",
"Hiragino Sans", "Hiragino Kaku Gothic ProN",
"Yu Gothic", "Meiryo", "MS Gothic",
sans-serif;
width: 960px;
text-align: justify;
margin: auto;
punctuation-trim: adjacent;
}

em
{
font-style: normal;
font-size: 120%;
font-weight: bold;
color: red;
font-family: "Helvetica Neue", "Helvetica", "Segoe UI", "Arial",
"JPAGothic", "IPAGothic",
"Hiragino Sans", "Hiragino Kaku Gothic ProN",
"Yu Gothic", "Meiryo", "MS Gothic",
sans-serif;
}

.miteruzochan
{
white-space: nowrap;
}

section
{
margin-bottom: 3em;
}

p:not(.noindent)
{
text-indent: 1em;
}

p
{
margin: 0 2em;
line-height: 3em;
}

.copy
{
font-size: 200%;
font-weight: bold;
font-style: italic;
text-align: center;
font-family: "Times New Roman",
"JPAMincho", "IPAMincho", "Hiragino Mincho ProN",
"Yu Mincho", "MS Mincho",
serif;
margin: 1em 0;
}

footer
{
font-size: 16px;
color: dimgray;
text-align: center;
line-height: 2em;
padding-bottom: 24px;
}

footer > div
{
margin: 24px 0;
}

.copyright
{
text-align: center;
margin: 24px 0;
}

footer a
{
color: darkslategray;
}

a
{
text-decoration: none;
}

div.paragraph
{
margin-bottom: 1.5em;
}

table
{
margin: auto;
}

tr:nth-child(odd)
{
background-color: lightgray;
}

th, td
{
padding: 8px 16px;
}

#title
{
text-align: left;
display: inline-block;
}

#translate
{
text-align: right;
display: inline-block;
width: 288px;
}

header
{
display: flex;
justify-content: space-between;
align-items: center;
}

button, input
{
font-size: 24px;
}

body
{
background-color: aquamarine;
}

table
{
margin: 24px auto 40px;
}

td
{
padding: 8px;
}

table, td
{
border: solid 1px;
background-color: white;
}

#paint
{
margin-bottom: 64px;
}

#paint > div
{
margin: 24px auto;
}

h1, .illust
{
text-align: center;
}

.radio
{
/* width: 704px; */
/* display: inline-block; */
vertical-align: middle;
line-height: 1.5em;
/* margin: auto; */
}

.button-area, .canvas-area
{
text-align: center;
}

.canvas-area
{
width: 480px;
height: 480px;
max-width: 100%;
position: relative;
padding: 0;
box-sizing: content-box;
}

.canvas-area:before
{
content: "";
display: block;
padding-top: 100%;
}

.canvas-area > canvas
{
position: absolute;
left: 0;
top: 0;
border: 1px solid;
max-width: 100%;
box-sizing: content-box;
padding: 0;
margin: 0;
}

.modal {
display: none;
position: fixed;
z-index: 1;
left: 0;
top: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.4);
}

.modal-content {
background-color: #fff;
margin: 15% auto;
padding: 20px;
border: 1px solid #888;
width: 400px;
text-align: center;
}

@media only screen and (max-width: 600px) {
.modal-content {
width: 70%;
}
}

Loading…
Cancel
Save