diff --git a/www/src/db_handler/db_interface.php b/www/src/db_handler/db_interface.php index 6493d26..f143b81 100644 --- a/www/src/db_handler/db_interface.php +++ b/www/src/db_handler/db_interface.php @@ -80,6 +80,16 @@ interface PostdataInterface { $order_by = 'path'); public function get_post_markdown($id); + + + // Returns an array of PostData information + // based on the tag search list + // + // Tag searchlist is comprised of space-separated + // tags. Each tag can have a weighting prefix, + // and some special tags exist (such as limit:N, + // order:S). + public function search_posts($taglist); } ?> \ No newline at end of file diff --git a/www/src/db_handler/mysql_handler.php b/www/src/db_handler/mysql_handler.php index 3eb5b4e..90f9adf 100644 --- a/www/src/db_handler/mysql_handler.php +++ b/www/src/db_handler/mysql_handler.php @@ -3,23 +3,7 @@ require_once 'analytics_interface.php'; require_once 'db_interface.php'; -function taglist_escape_tag($tag) { - return preg_replace_callback('/[\WZ]/', function($match) { - return "Z" . ord($match[0]); - }, strtolower($tag)); -} - -function taglist_to_sql_string($post_tags) { - $post_tags = array_unique($post_tags); - $post_tags = array_map(function($val) { - return taglist_escape_tag($val); - }, $post_tags); - - asort($post_tags); - $post_tags = join(' ', $post_tags); - - return $post_tags; -} +require_once 'mysql_taglist_handling.php'; class MySQLHandler implements PostdataInterface { @@ -128,7 +112,7 @@ class MySQLHandler $post_path, substr_count($post_path, "/"), $data['title'], - taglist_to_sql_string($post_tags), + TagList\create_db_str($post_tags), $data['brief'] ?? null ]; @@ -292,8 +276,8 @@ class MySQLHandler 'path DESC' => true, 'created_at' => true, 'created_at DESC' => true, - 'modified_at' => true, - 'modified_at DESC' => true + 'updated_at' => true, + 'updated_at DESC' => true ]; if(!isset($allowed_ordering[$order_by])) { @@ -342,6 +326,52 @@ class MySQLHandler return $data['post_markdown']; } + + public function search_posts($taglist) { + $qry = " + SELECT * + FROM posts + WHERE MATCH(post_tags) AGAINST (? IN BOOLEAN MODE) + "; + + $search_data = TagList\create_db_search($taglist); + + $order_by = $search_data['modifiers']['order_by'] ?? 'updated_at'; + $limit = intval($search_data['modifiers']['limit'] ?? 20); + $offset = intval($search_data['modifiers']['offset'] ?? 0); + + if($limit > 100) { + throw new Exception('Search limit above maximum (max 100 results per search)'); + } + + $allowed_ordering = [ + 'path' => true, + 'path DESC' => true, + 'created_at' => true, + 'created_at DESC' => true, + 'updated_at' => true, + 'updated_at DESC' => true + ]; + // TODO move this to a class var + + if(!isset($allowed_ordering[$order_by])) { + throw new Exception('Search order not allowed'); + } + $order_by = 'post_' . $order_by; + + $qry = $qry . " ORDER BY " . $order_by . " LIMIT ? OFFSET ?"; + + $search_results = $this->_exec($qry, "sii", $search_data['parameter_string'], + $limit, $offset)->fetch_all(MYSQLI_ASSOC); + + $outdata = []; + foreach($search_results AS $post_element) { + $outdata []= + $this->process_postdata($post_element); + } + + return $outdata; + } } ?> \ No newline at end of file diff --git a/www/src/db_handler/mysql_taglist_handling.php b/www/src/db_handler/mysql_taglist_handling.php new file mode 100644 index 0000000..76a3ef9 --- /dev/null +++ b/www/src/db_handler/mysql_taglist_handling.php @@ -0,0 +1,76 @@ + $search_modifiers, + 'parameter_string' => $search_params + ]; +} + +?> \ No newline at end of file diff --git a/www/src/db_handler/post_handler.php b/www/src/db_handler/post_handler.php index 06fd3fc..8c6ad3f 100644 --- a/www/src/db_handler/post_handler.php +++ b/www/src/db_handler/post_handler.php @@ -56,6 +56,17 @@ class PostHandler { return $out_list; } + + public function search_posts($search_query) { + $search_results = $this->db->search_posts($search_query); + + $out_list = []; + foreach($search_results as $search_result) { + array_push($out_list, new Post($this, $search_result, $this->site_defaults)); + } + + return $out_list; + } } ?> \ No newline at end of file