aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoralyx <alyx@aleteoryx.me>2024-05-24 19:53:30 -0400
committeralyx <alyx@aleteoryx.me>2024-05-24 19:53:30 -0400
commitf0ceb70d0d31cf95ea5939857b60e0e427cba52b (patch)
treef84e9bf6f480c27c412225ce879a70c7d4ba3f9c
parent46adf996902fb8fb4ce8dbb9b2b0db6203f841e8 (diff)
downloadvisitors_dot_php-f0ceb70d0d31cf95ea5939857b60e0e427cba52b.tar.gz
visitors_dot_php-f0ceb70d0d31cf95ea5939857b60e0e427cba52b.tar.bz2
visitors_dot_php-f0ceb70d0d31cf95ea5939857b60e0e427cba52b.zip
JSON DB
-rw-r--r--visitors.php84
1 files changed, 78 insertions, 6 deletions
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;
+ }
+}