From f0ceb70d0d31cf95ea5939857b60e0e427cba52b Mon Sep 17 00:00:00 2001 From: alyx Date: Fri, 24 May 2024 19:53:30 -0400 Subject: JSON DB --- visitors.php | 84 +++++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 78 insertions(+), 6 deletions(-) (limited to 'visitors.php') diff --git a/visitors.php b/visitors.php index 2b5001b..5707482 100644 --- a/visitors.php +++ b/visitors.php @@ -7,9 +7,9 @@ define('GIT_REPO', 'https://git.aleteoryx.me/cgit/visitors_dot_php/'); /* CONFIG OPTIONS - COSMETIC */ -// Custom CSS: string +// Custom CSS: ?string // -// Will be injected below the builtin CSS. Respects `use_path_info` when being served. +// Will be injected after the builtin CSS. Respects `use_path_info` when being served. //$config['custom_css'] = 'body { background: red; }'; @@ -18,7 +18,7 @@ define('GIT_REPO', 'https://git.aleteoryx.me/cgit/visitors_dot_php/'); // // Toggles the builtin CSS -$config['builtin_css'] = TRUE; +$config['builtin_css'] = true; // Form mode: choice @@ -44,7 +44,7 @@ $config['form_mode'] = 0; $config['email_display'] = 0; -// E-Mail icon: string +// E-Mail icon: ?string // // Should be the link to an icon for email display modes 0 and 1. Supports base64. If null or empty, defaults to a builtin image. @@ -55,10 +55,11 @@ $config['email_display'] = 0; // Send assets via PATH_INFO: bool // -// If true, assets like CSS, GIFs, etc, will be served from `/visitors.php/foo.css`. +// If true, assets like CSS, GIFs, etc, will be served from URLs like `/visitors.php/foo.css`. // Otherwise, inline them into a single HTML document. +// Only enable this if your webserver supports PATH_INFO. -$config['use_path_info'] = FALSE; +$config['use_path_info'] = false; // Database path: string @@ -76,3 +77,74 @@ $config['db'] = 'visitors.csv'; /* --- END OF CONFIG, CODE BELOW, PROBABLY DON'T EDIT PAST THIS POINT --- */ +// db_row: ['id' => int (only for list_rows), 'name' => string, 'message' => string, 'email' => ?string, 'website' => ?string, 'timestamp' => string (or DateTimeInterface for list_rows)] +// message is pre-escaped at insert time. +// timestamp is DateTimeInterface::ISO8601_EXPANDED format. + +abstract class Database { + public function append_row(string $name, string $message, ?string $email = NULL, ?string $website = NULL) { + $timestamp = date(DATE_ISO8601_EXPANDED); + $this->_append_row(compact('name', 'message', 'email', 'website', 'timestamp')); + } + + public function list_rows(): array { + $data = $this->_list_rows(); + foreach($data as &$row) { + $row['timestamp'] = DateTime::createFromFormat(DATE_ISO8601_EXPANDED, $row['timestamp']); + } + return $data; + } + + public function delete_row(int $id): bool { + return $this->_delete_row($id); + } + + abstract protected function _append_row(array $db_row); + abstract protected function _list_rows(): array; + abstract protected function _delete_row(int $id): bool; +} + +// notes: `id` is not stable +final class JsonDatabase extends Database { + private string $file; + private array $data; + + public function __construct(string $file) { + if (file_exists($file)) + $this->data = json_decode(file_get_contents($file), associative: true); + else + $this->data = array(); + + $this->file = $file; + } + + private function save() { + file_put_contents($this->file, json_encode($this->data)); + } + + protected function _append_row(array $db_row) { + array_unshift($this->data, $db_row); + $this->save(); + } + + protected function _list_rows(): array { + $data = $this->data; + + foreach($data as $id => &$row) { + $row['id'] = $id; + } + + return $data; + } + + protected function _delete_row(int $id): bool { + if (!isset($this->data[$id])) + return false; + + unset($this->data[$id]); + $this->data = array_values($this->data); + $this->save(); + + return true; + } +} -- cgit v1.2.3-70-g09d2