Files
racket-chatgpt-bootstrap/private/usersettings.php
T
www-data 2f2e8869d6 Reorganize PHP internals and static assets
Move shared PHP code into private/, move JavaScript files into js/, and block direct access to private/. Remove unused API key and cache artifacts from the working tree.
2026-05-26 11:32:36 +02:00

112 lines
2.9 KiB
PHP

<?php
/*
* usersettings.php
*
* Tiny SQLite-backed key/value store for per-user UI preferences.
*/
class UserSettingsStoreException extends Exception
{
}
class UserSettingsStore
{
private $db;
public function __construct($dbFile)
{
$dir = dirname($dbFile);
if (!is_dir($dir)) {
if (!mkdir($dir, 0700, true)) {
throw new UserSettingsStoreException('Could not create database directory: ' . $dir);
}
}
$this->db = new PDO('sqlite:' . $dbFile);
$this->db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$this->db->exec('PRAGMA journal_mode = WAL');
$this->db->exec('PRAGMA busy_timeout = 5000');
$this->init();
}
private function init()
{
$this->db->exec(
'CREATE TABLE IF NOT EXISTS user_settings (
user_id INTEGER NOT NULL,
setting_key TEXT NOT NULL,
setting_value TEXT NOT NULL,
created_at INTEGER NOT NULL,
updated_at INTEGER NOT NULL,
PRIMARY KEY(user_id, setting_key)
)'
);
}
public function get($userId, $key, $default = null)
{
$stmt = $this->db->prepare(
'SELECT setting_value
FROM user_settings
WHERE user_id = :user_id
AND setting_key = :setting_key'
);
$stmt->execute(array(
':user_id' => $this->safeUserId($userId),
':setting_key' => $this->safeKey($key),
));
$row = $stmt->fetch(PDO::FETCH_ASSOC);
return $row ? (string)$row['setting_value'] : $default;
}
public function set($userId, $key, $value)
{
$now = time();
$stmt = $this->db->prepare(
'INSERT INTO user_settings
(user_id, setting_key, setting_value, created_at, updated_at)
VALUES
(:user_id, :setting_key, :setting_value, :created_at, :updated_at)
ON CONFLICT(user_id, setting_key)
DO UPDATE SET
setting_value = excluded.setting_value,
updated_at = excluded.updated_at'
);
$stmt->execute(array(
':user_id' => $this->safeUserId($userId),
':setting_key' => $this->safeKey($key),
':setting_value' => (string)$value,
':created_at' => $now,
':updated_at' => $now,
));
}
private function safeUserId($userId)
{
$userId = (int)$userId;
if ($userId <= 0) {
throw new UserSettingsStoreException('Invalid user id.');
}
return $userId;
}
private function safeKey($key)
{
$key = trim((string)$key);
if (!preg_match('/^[a-z0-9_.-]{1,80}$/', $key)) {
throw new UserSettingsStoreException('Invalid setting key.');
}
return $key;
}
}