From 754aba02a8e0587915829a56e7cfab09003b8ac1 Mon Sep 17 00:00:00 2001 From: Shish Date: Sat, 7 Sep 2024 17:01:20 +0100 Subject: [PATCH] [WIP] limit=X meta-tag, see #1153 This seems close to working, except that "page size" and "total number of search results" are two distinct concepts, and SQL LIMIT is used for page size already, so it doesn't work to also use it for total number of search results... --- core/imageboard/search.php | 11 +++++++++-- ext/index/events.php | 1 + ext/index/main.php | 4 +++- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/core/imageboard/search.php b/core/imageboard/search.php index 7594acf6e..4b8622686 100644 --- a/core/imageboard/search.php +++ b/core/imageboard/search.php @@ -72,6 +72,7 @@ class SearchParameters /** @var ImgCondition[] */ public array $img_conditions = []; public ?string $order = null; + public ?int $limit = null; /** * Turn a human input string into a an abstract search query @@ -87,9 +88,10 @@ public static function from_terms(array $terms): SearchParameters $stpen = 0; // search term parse event number foreach (array_merge([null], $terms) as $term) { $stpe = send_event(new SearchTermParseEvent($stpen++, $term, $terms)); - $sp->order ??= $stpe->order; $sp->img_conditions = array_merge($sp->img_conditions, $stpe->img_conditions); $sp->tag_conditions = array_merge($sp->tag_conditions, $stpe->tag_conditions); + $sp->order ??= $stpe->order; + $sp->limit ??= $stpe->limit; } $sp->order ??= "images.".$config->get_string(IndexConfig::ORDER); @@ -134,6 +136,9 @@ private static function find_images_internal(int $start = 0, ?int $limit = null, } $params = SearchParameters::from_terms($tags); + if ($params->limit !== null) { + $limit = $limit ? min($params->limit, $limit) : $params->limit; + } $querylet = self::build_search_querylet($params, $limit, $start); return $database->get_all_iterable($querylet->sql, $querylet->variables); } @@ -453,7 +458,9 @@ public static function build_search_querylet( if (!is_null($limit)) { $query->append(new Querylet(" LIMIT :limit ", ["limit" => $limit])); - $query->append(new Querylet(" OFFSET :offset ", ["offset" => $offset])); + if (!is_null($offset)) { + $query->append(new Querylet(" OFFSET :offset ", ["offset" => $offset])); + } } return $query; diff --git a/ext/index/events.php b/ext/index/events.php index babc70b98..ef3d3c3c7 100644 --- a/ext/index/events.php +++ b/ext/index/events.php @@ -24,6 +24,7 @@ class SearchTermParseEvent extends Event /** @var TagCondition[] */ public array $tag_conditions = []; public ?string $order = null; + public ?int $limit = null; /** * @param string[] $context diff --git a/ext/index/main.php b/ext/index/main.php index c569d6768..f42a06d2e 100644 --- a/ext/index/main.php +++ b/ext/index/main.php @@ -240,10 +240,12 @@ public function onSearchTermParse(SearchTermParseEvent $event): void // recommended to change homepage to "post/list/order:dailyshuffle/1" $seed = (int)date("Ymd"); $event->order = $database->seeded_random($seed, "images.id"); + } elseif (preg_match("/^limit[=:](\d+)$/i", $event->term, $matches)) { + $event->limit = intval($matches[1]); } // If we've reached this far, and nobody else has done anything with this term, then treat it as a tag - if ($event->order === null && $event->img_conditions == [] && $event->tag_conditions == []) { + if ($event->order === null && $event->limit === null && $event->img_conditions == [] && $event->tag_conditions == []) { assert(is_string($event->term)); $event->add_tag_condition(new TagCondition($event->term, !$event->negative)); }