From 890dad24d6c095c41e6358b2a6cb61f1b6c2f6ad Mon Sep 17 00:00:00 2001 From: winter Date: Sun, 26 Jan 2025 15:25:17 +0000 Subject: add user settings / preferences --- Digitigrade/UserSettings.php | 169 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 169 insertions(+) create mode 100644 Digitigrade/UserSettings.php (limited to 'Digitigrade/UserSettings.php') diff --git a/Digitigrade/UserSettings.php b/Digitigrade/UserSettings.php new file mode 100644 index 0000000..4a27014 --- /dev/null +++ b/Digitigrade/UserSettings.php @@ -0,0 +1,169 @@ +user = $user; + $this->db = Db::getInstance()->getPdo(); + if (!$this->get('settings.initialised')) { + $this->resetAll(); + } + } + + /** + * Gets a setting's value. + * @param string $key which setting to get + * @return ?string the value, or null if not set + */ + public function get(string $key): ?string { + $stmt = $this->db->prepare('SELECT value FROM user_setting WHERE name = ? AND user_id = ?'); + $stmt->execute([$key, $this->user->id]); + return $stmt->fetchColumn(0) ?: null; + } + + /** + * Gets a boolean setting's value. + * @param string $key which setting to get + * @return ?bool the value, or null if not set + */ + public function getBool(string $key): ?bool { + return match ($this->get($key)) { + '', 'false' => false, + '1', 'true' => true, + default => null + }; + } + + /** + * Sets the value of a setting. + * @param string $key which setting to modify + * @param string $value the new value + * @return void + */ + public function set(string $key, string $value) { + $stmt = $this->db->prepare(<<execute([$this->user->id, $key, $value]); + } + + public function setBool(string $key, bool $value) { + $this->set($key, $value ? 'true' : 'false'); + } + + /** + * Checks whether a setting is set. + * @param string $key which setting to check + * @return bool if it's set (has a value) or not + */ + public function isset(string $key): bool { + $stmt = $this->db->prepare('SELECT count(*) FROM user_setting WHERE name = ? AND user_id = ?'); + $stmt->execute([$key, $this->user->id]); + return $stmt->fetchColumn(0) > 0; + } + + /** + * Unsets a setting. + * @param string $key which setting to remove + * @return void + */ + public function unset(string $key) { + $stmt = $this->db->prepare('DELETE FROM user_setting WHERE name = ? AND user_id = ?'); + $stmt->execute([$key, $this->user->id]); + } + + /** + * Gets a list of all currently-set settings. + * @return array{key: string, value: string} array of keys to values + */ + public function getAll(): array { + $stmt = $this->db->prepare('SELECT name, value FROM user_setting WHERE user_id = ?'); + $stmt->execute([$this->user->id]); + $items = $stmt->fetchAll(); + $result = []; + foreach ($items as $row) { + $result[$row['name']] = $row['value']; + } + return $result; + } + + /** + * Gets a list of all settings in a given prefix. + * @param string $prefix prefix to look in (not including the trailing dot) + * @return array{key: string, value: string} array of keys to values + */ + public function getAllInPrefix(string $prefix): array { + $stmt = $this->db->prepare('SELECT name, value FROM user_setting WHERE name ^@ ? AND user_id = ?'); + $stmt->execute(["$prefix.", $this->user->id]); + $items = $stmt->fetchAll(); + $result = []; + foreach ($items as $row) { + $result[$row['name']] = $row['value']; + } + return $result; + } + + /** + * Gets a list of all first-level prefixes. + * @return string[] + */ + public function getAllPrefixes(): array { + return array_unique(array_map( + fn($x) => explode('.', $x, 2)[0], + array_keys($this->getAll()) + )); + } + + /** + * Gets information (name, description, default value) for a given setting. + * @param string $key which setting to look up + * @return ?array{item: string, value: string} associative array of info, + * or null if none is available + */ + public function getInfo(string $key): ?array { + $this->loadDefinitions(); + return $this->info[$key] ?? null; + } + + /** + * Merges new keys from the settings definition file into the settings + * without overwriting existing values. + * @return void + */ + public function mergeUpdates() { + $this->initialise(false); + } + + /** + * Sets all defined settings back to their default values. + * @return void + */ + public function resetAll() { + $this->initialise(true); + } + + private function loadDefinitions() { + if (!isset($this->info)) { + $this->info = parse_ini_file(self::DEFINITIONS_INI_PATH, process_sections: true); + } + } + + private function initialise(bool $overwriteExisting) { + $this->loadDefinitions(); + foreach ($this->info as $key => $setting) { + if ($overwriteExisting || !$this->isset($key)) { + $this->set($key, $setting['default']); + } + } + $this->set('settings.initialised', true); + } +} \ No newline at end of file -- cgit v1.3