aboutsummaryrefslogtreecommitdiffhomepage
path: root/Digitigrade
diff options
context:
space:
mode:
Diffstat (limited to 'Digitigrade')
-rw-r--r--Digitigrade/GlobalSettings.php136
1 files changed, 136 insertions, 0 deletions
diff --git a/Digitigrade/GlobalSettings.php b/Digitigrade/GlobalSettings.php
new file mode 100644
index 0000000..435c85a
--- /dev/null
+++ b/Digitigrade/GlobalSettings.php
@@ -0,0 +1,136 @@
+<?php
+namespace Digitigrade;
+
+class GlobalSettings extends Singleton {
+ private const DEFINITIONS_INI_PATH = __DIR__ . '/../settings.global.ini';
+
+ private \PDO $db;
+ private array $info;
+
+ protected function __construct() {
+ $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 global_setting WHERE name = ?');
+ $stmt->execute([$key]);
+ return $stmt->fetchColumn(0) ?: 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(<<<END
+ INSERT INTO global_setting(name, value) VALUES (?, ?)
+ ON CONFLICT (name) DO UPDATE SET value = EXCLUDED.value
+ END);
+ $stmt->execute([$key, $value]);
+ }
+
+ /**
+ * 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 global_setting WHERE name = ?');
+ $stmt->execute([$key]);
+ 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 global_setting WHERE name = ?');
+ $stmt->execute([$key]);
+ }
+
+ /**
+ * 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->query('SELECT name, value FROM global_setting');
+ $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 global_setting WHERE name ^@ ?');
+ $stmt->execute(["$prefix."]);
+ $items = $stmt->fetchAll();
+ $result = [];
+ foreach ($items as $row) {
+ $result[$row['name']] = $row['value'];
+ }
+ return $result;
+ }
+
+ /**
+ * 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