From a3604d21c9660bac95f8eaf3cbace27039f8353c Mon Sep 17 00:00:00 2001 From: David Bailey Date: Thu, 27 Mar 2025 23:31:29 +0100 Subject: [PATCH] feat(database): :sparkles: re-add per-post counters to track page views etc. --- docker_dev/mysql_schema.sql | 2 ++ www/src/db_handler/db_interface.php | 2 ++ www/src/db_handler/mysql_handler.php | 24 +++++++++++++++++++++++- www/src/db_handler/post.php | 7 ++++++- www/src/db_handler/post_handler.php | 4 ++++ www/src/serve/post.php | 21 +++++++++++++++------ www/templates/pathed_content.html | 2 +- 7 files changed, 53 insertions(+), 9 deletions(-) diff --git a/docker_dev/mysql_schema.sql b/docker_dev/mysql_schema.sql index 294266d..48f5cb2 100644 --- a/docker_dev/mysql_schema.sql +++ b/docker_dev/mysql_schema.sql @@ -26,6 +26,8 @@ CREATE TABLE dev_posts ( post_metadata JSON DEFAULT NULL, post_settings_cache JSON DEFAULT NULL, + post_counters JSON DEFAULT NULL, + PRIMARY KEY(post_id), CONSTRAINT unique_post UNIQUE (post_path), diff --git a/www/src/db_handler/db_interface.php b/www/src/db_handler/db_interface.php index 2ca64d1..c41b31a 100644 --- a/www/src/db_handler/db_interface.php +++ b/www/src/db_handler/db_interface.php @@ -73,6 +73,8 @@ interface PostdataInterface { public function set_postdata($data); public function set_post_markdown($id, $markdown); + public function increment_post_counter($path, $counter = 'views', $value = 1); + public function get_postdata($path); // Returns a key-value pair of child paths => child data public function get_post_children($path, diff --git a/www/src/db_handler/mysql_handler.php b/www/src/db_handler/mysql_handler.php index 88d14c9..105be1d 100644 --- a/www/src/db_handler/mysql_handler.php +++ b/www/src/db_handler/mysql_handler.php @@ -1,6 +1,5 @@ _exec($qry, "is", $id, $markdown); } + public function increment_post_counter($path, $counter = 'views', $value = 1) { + $path = sanitize_post_path($path); + + $qry = + "UPDATE {$this->db_prefix}_posts + SET post_counters = JSON_SET(COALESCE(post_counters, \"{}\"), ?, COALESCE(JSON_EXTRACT(post_counters, ?), 0) + ?) + WHERE post_path = ?"; + + $json_path = "$.{$counter}"; + + $this->_exec($qry, "ssds", $json_path, $json_path, $value, $path); + } + private function get_post_settings($post_path) { $post_path = sanitize_post_path($post_path); @@ -252,6 +267,13 @@ class MySQLHandler $post_settings = $this->get_post_settings($data['post_path']); } + if(isset($data['post_counters'])) { + $outdata['counters'] = json_decode($data['post_counters'], true); + } + else { + $outdata['counters'] = []; + } + $outdata = array_merge($post_settings, $post_metadata, $outdata); $outdata['host'] ??= $this->hostname; diff --git a/www/src/db_handler/post.php b/www/src/db_handler/post.php index 1b0e5bd..d26ec04 100644 --- a/www/src/db_handler/post.php +++ b/www/src/db_handler/post.php @@ -21,7 +21,8 @@ class Post implements ArrayAccess { 'title' => '404 Page', 'metadata' => [ 'type' => '404' - ] + ], + 'markdown' => 'Whoops! The dergen could not quite find that...' ]; return $post_data; @@ -139,6 +140,10 @@ class Post implements ArrayAccess { $this->data = $data; } + public function increment_counter($type = 'views', $value = 1) { + $this->handler->increment_post_counter($this->data['path'], $type, $value); + } + public function __get($name) { if($name == 'html') { return $this->get_html(); diff --git a/www/src/db_handler/post_handler.php b/www/src/db_handler/post_handler.php index 8c6ad3f..51fbbe2 100644 --- a/www/src/db_handler/post_handler.php +++ b/www/src/db_handler/post_handler.php @@ -46,6 +46,10 @@ class PostHandler { return ($this->markdown_engine)($post); } + public function increment_post_counter(...$opts) { + $this->db->increment_post_counter(...$opts); + } + public function get_children_for($post, ...$search_opts) { $child_list = $this->db->get_post_children($post->path, ...$search_opts); diff --git a/www/src/serve/post.php b/www/src/serve/post.php index 1a8aa33..46ef71c 100644 --- a/www/src/serve/post.php +++ b/www/src/serve/post.php @@ -58,7 +58,7 @@ if($REQUEST_PATH == '/upload') { render_root_template('upload.html'); die(); } -if($REQUEST_PATH == '/search') { +if($REQUEST_PATH == '/search/') { $search_results = []; $display_type = 'none'; @@ -105,13 +105,22 @@ if($REQUEST_PATH == '/search') { } $post = $adapter->get_post($REQUEST_PATH); -render_post($post); - -die(); if(!isset($post)) { - render_404(); - die(); + $error_page = $SITE_CONFIG['site_defaults']; + $error_page['path'] = '/404'; + $error_page['title'] = '404 oh no'; + $error_page['basename'] = '404.md'; + + render_root_template('derg_error.html', [ + 'page' => $error_page, + 'error_code' => '404 Hoard not found!', + 'error_description' => "Looks like we couldn't find `" . $REQUEST_PATH . "` for you. Check in later!" + ]); +} +else { + $post->increment_counter(); + render_post($post); } diff --git a/www/templates/pathed_content.html b/www/templates/pathed_content.html index 92b8bd7..c5dc10f 100644 --- a/www/templates/pathed_content.html +++ b/www/templates/pathed_content.html @@ -22,7 +22,7 @@ {%endblock%} - This page was created on {{ page.created_at }}, last edited {{ page.updated_at }}, and was viewed {{ page.view_count }} times~ + This page was created on {{ page.created_at }}, last edited {{ page.updated_at }}, and was viewed {{ page.counters.views }} times~