<?php
require_once("../../lib/func.php");
define("MY_DIR", relpath_to_abspath("."));
define("APP_ID", "LoginTest");
define("LOGIN_TABLE", check_login_table(APP_ID));
define("USER_VAR_TABLE", check_user_var_table(APP_ID));
//------------------------------------------ 関数定義
// コマンドを実行する
// 最後に別ページに飛ばすためスクリプトは終了する
function exec_cmd($cmd)
{
switch ($cmd) {
case "signup":
// POSTされた名前とパスワードを取得
$name = $_POST["user_name"] ?? "";
$pass = $_POST["user_pass"] ?? "";
$db_name = db_encode($name);
$db_pass = db_encode($pass);
if ($name == "") {
// 名前欄が空白
// エラーをセッションに記録して登録フォームに戻る
set_session_var("error", "名前欄が空白なので登録不可です。");
header(redirect("s02-signup.php"));
}
else if (add_table_data(DB_NAME, LOGIN_TABLE, ["name"=>$db_name, "pass"=>$db_pass])) {
// ユーザー登録成功
// メッセージをセッションに記録してメインメージを表示する
set_session_var("message", "ユーザー「${name}」を登録しました。");
header(redirect("s02.php"));
}
else {
// 名前重複のためユーザー登録失敗
// エラーをセッションに記録して登録フォームに戻る
set_session_var("error", "既存ユーザーと同じ名前は登録不可です。");
header(redirect("s02-signup.php"));
}
exit(0);
case "deluser":
// POSTされたユーザーIDのリストを得る
$id_list = array_map("intval", $_POST["ids"] ?? array());
$ids = implode(",", $id_list);
// ユーザー変数テーブルとログインテーブルからユーザーを消す
delete_table_data(DB_NAME, USER_VAR_TABLE, "where id in ($ids)");
$count = delete_table_data(DB_NAME, LOGIN_TABLE, "where id in ($ids)");
$message = "${count} 件のデータを削除しました。";
// ログイン中のユーザーIDを削除する場合はログアウトする
$login_id = peek_session_var("user_id") ?? 0;
if (in_array($login_id, $id_list)) {
delete_session_var("user_id");
delete_session_var("user_name");
$message .= "<br>ログアウトしました。";
}
// 管理室を表示する
set_session_var("message", $message);
header(redirect("s02-admin.php"));
exit(0);
case "login":
// POSTされた名前とパスワードを取得
$name = $_POST["user_name"] ?? "";
$pass = $_POST["user_pass"] ?? "";
$db_name = db_encode($name);
$db_pass = db_encode($pass);
// ログイン認証
$list = get_table_data(DB_NAME, LOGIN_TABLE, "where name='$db_name' and pass='$db_pass'");
if (count($list) > 0) {
// ログイン成功
// ログイン情報をセッションに記録し、メインページを表示する
$id = $list[0]["id"];
set_session_var("user_id", $id);
set_session_var("user_name", $name);
header(redirect("s02.php"));
}
else {
// ログイン失敗
// エラーをセッションに記録してログインフォームに戻る
set_session_var("error", "名前またはパスワードが違います。");
header(redirect("s02-login.php"));
}
exit(0);
case "logout":
// ログイン情報を消し、メインページを表示する
delete_session_var("user_id");
delete_session_var("user_name");
set_session_var("message", "ログアウトしました。");
header(redirect("s02.php"));
exit(0);
default:
abort("コマンド [$cmd] は未定義です。");
}
}
// おみくじを引く
function get_oracle()
{
// おみくじデータ [出現頻度、運勢、得点]
$oracle_list = [
[50, "小吉", 1],
[25, "中吉", 2],
[15, "大吉", 3],
[7, "秀吉", 1000],
[3, "信長", 1000000],
];
// 出現頻度の合計値を得る
$sum = 0;
foreach ($oracle_list as $oracle) {
$sum += $oracle[0];
}
// 出現頻度に比例した確率でランダムなおみくじを選ぶ
$rand = random_int(0, $sum - 1);
foreach ($oracle_list as $oracle) {
if (($rand -= $oracle[0]) < 0) {
return [$oracle[1], $oracle[2]];
}
}
return ["ありえない", 0];
}
// ログイン時のHTMLコンテンツを作る
function html_with_user($user_id, $user_name)
{
// おみくじを引く
[$message, $point] = get_oracle();
// ユーザーの合計ポイントを更新する
$total = get_user_var(APP_ID, $user_id, "total") ?? 0;
$total += $point;
set_user_var(APP_ID, $user_id, "total", $total);
// セッション作成時に指定されたlifetimeを得る
$params = session_get_cookie_params();
$lifetime = $params["lifetime"] ?? 0;
// コンテンツを作って返す
$mydir = MY_DIR;
$safe_name = htmlspecialchars($user_name);
return <<<HTML_LOGIN
<p>${safe_name}さんの運勢は【${message} ${point}点】 です。<br>
現在までの合計ポイントは ${total} 点です。</p>
<p>
※ <a href="$mydir/s02.php?cmd=logout">ログアウトする</a><br>
※ <a href="$mydir/s02-admin.php">管理室</a>(本来は認証あり)<br>
※ セッション終了の予定時刻まで、およそ <span id="count_down">$lifetime</span> 秒<br>
</p>
<script>
var n = $lifetime;
var e = document.getElementById("count_down");
var i = setInterval(function() {if (n>0) e.innerHTML=--n; else clearInterval(i);}, 1000);
</script>
HTML_LOGIN;
}
// ログアウト時のHTMLコンテンツを作る
function html_no_user()
{
// メッセージがあれば得る
$message = get_session_var("message") ?? "";
if ($message == "") {
$message = "あなたは現在ログインしていません。";
}
// コンテンツを作って返す
$mydir = MY_DIR;
return <<<HTML_NOLOGIN
<p>$message</p>
<p>
※ ユーザー登録済みなら → <a href="$mydir/s02-login.php">ログインする</a><br>
※ 未登録の方は → <a href="$mydir/s02-signup.php">ユーザー登録する</a><br>
※ 管理者専用 → <a href="$mydir/s02-admin.php">管理室</a>(本来は認証あり)<br>
</p>
HTML_NOLOGIN;
}
//------------------------------------------ 以下メイン処理
// セッションを開始する
start_my_session(60);
// 引数があればコマンドとして実行し、スクリプトを終了する
if (isset($_POST["cmd"])) {
exec_cmd($_POST["cmd"]);
/* NOT REACHED */
}
if (isset($_GET["cmd"])) {
exec_cmd($_GET["cmd"]);
/* NOT REACHED */
}
// ログイン中か調べる
$user_id = peek_session_var("user_id");
$user_name = peek_session_var("user_name");
if ($user_id > 0) {
// ログイン中の場合
$contents = html_with_user($user_id, $user_name);
}
else {
// ログインしていない場合
$contents = html_no_user();
}
$contents .= "\n";
// HTTPヘッダの出力
header("Cache-Control: no-cache"); // ブラウザにキャッシュさせない
?>
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>永続的なログイン処理</title>
</head>
<body>
<p>■<a href="<?= MY_DIR ?>/s02.php">永続的なログイン処理</a></p>
<?= $contents ?>
</body>
</html>