diff options
| author | Murtaza Sultani <sultani@data-quest.de> | 2025-07-25 12:25:37 +0200 |
|---|---|---|
| committer | Murtaza Sultani <sultani@data-quest.de> | 2025-07-25 12:25:37 +0200 |
| commit | d83a8347ed60b06b360827dc8a1026a70815a483 (patch) | |
| tree | 358db42c7c3f35dc6c599c36b91baee0b8039a79 /lib | |
| parent | 1d51d3baf430da6b4573b42aae5f0db9cea838c1 (diff) | |
Resolve "Forumsuche ohne Reload"
Closes #5747
Merge request studip/studip!4388
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/classes/JsonApi/Routes/Forum/ForumDiscussionIndex.php | 65 | ||||
| -rw-r--r-- | lib/models/Forum/ForumDiscussion.php | 54 |
2 files changed, 112 insertions, 7 deletions
diff --git a/lib/classes/JsonApi/Routes/Forum/ForumDiscussionIndex.php b/lib/classes/JsonApi/Routes/Forum/ForumDiscussionIndex.php index 140a502..83af8ac 100644 --- a/lib/classes/JsonApi/Routes/Forum/ForumDiscussionIndex.php +++ b/lib/classes/JsonApi/Routes/Forum/ForumDiscussionIndex.php @@ -12,7 +12,17 @@ use Forum\ForumDiscussion; class ForumDiscussionIndex extends JsonApiController { protected $allowedPagingParameters = ['offset', 'limit']; - protected $allowedFilteringParameters = ['last-visit']; + protected $allowedFilteringParameters = [ + 'last-visit', + 'keyword', + 'begin', + 'end', + 'topic-ids', + 'type-ids', + 'tag-ids', + 'user-ids', + 'status' + ]; protected $allowedIncludePaths = [ \JsonApi\Schemas\Forum\ForumCategory::REL_TOPICS, \JsonApi\Schemas\Forum\ForumDiscussion::REL_CATEGORY, @@ -35,14 +45,61 @@ class ForumDiscussionIndex extends JsonApiController throw new AuthorizationFailedException(); } - $filtering = $this->getQueryParameters()->getFilteringParameters() ?: []; - $last_visit = $filtering['last-visit'] ?? 0; + $filters = $this->getFilter(); + if ($filters) { + $_SESSION['forum'][$range->id]['search_filter'] = $filters; + } - $discussions = ForumDiscussion::getCourseDiscussions($range->id, $last_visit); + $discussions = ForumDiscussion::getCourseDiscussions($range->id, $filters); return $this->getPaginatedContentResponse( array_slice($discussions, ...$this->getOffsetAndLimit()), count($discussions) ); } + + private function getFilter(): array + { + $filtering = $this->getQueryParameters()->getFilteringParameters() ?: []; + + $discussion_filter = []; + + if (isset($filtering['last-visit'])) { + $discussion_filter['last_visit'] = (int) $filtering['last-visit']; + } + + if (isset($filtering['keyword'])) { + $discussion_filter['keyword'] = $filtering['keyword']; + } + + if (isset($filtering['status'])) { + $discussion_filter['status'] = (int) $filtering['status']; + } + + if (isset($filtering['begin'])) { + $discussion_filter['begin'] = (int) $filtering['begin']; + } + + if (isset($filtering['end'])) { + $discussion_filter['end'] = (int) $filtering['end']; + } + + if (isset($filtering['topic-ids'])) { + $discussion_filter['topic_ids'] = explode(',', $filtering['topic-ids']); + } + + if (isset($filtering['type-ids'])) { + $discussion_filter['type_ids'] = explode(',', $filtering['type-ids']); + } + + if (isset($filtering['tag-ids'])) { + $discussion_filter['tag_ids'] = explode(',', $filtering['tag-ids']); + } + + if (isset($filtering['user-ids'])) { + $discussion_filter['user_ids'] = explode(',', $filtering['user-ids']); + } + + return $discussion_filter; + } } diff --git a/lib/models/Forum/ForumDiscussion.php b/lib/models/Forum/ForumDiscussion.php index ce648fa..0dae82e 100644 --- a/lib/models/Forum/ForumDiscussion.php +++ b/lib/models/Forum/ForumDiscussion.php @@ -80,9 +80,12 @@ class ForumDiscussion extends SimpleORMap } /** + * @param string $range_id course_id or institute_id. + * @param array $filter Optional: filters to apply. + * * @return self[] */ - public static function getCourseDiscussions($range_id, $last_visit = 0): array + public static function getCourseDiscussions(string $range_id, array $filter = []): array { $query = [ "SELECT @@ -91,13 +94,58 @@ class ForumDiscussion extends SimpleORMap FROM forum_discussions AS discussions JOIN forum_postings as postings USING (discussion_id) JOIN forum_topics AS topics USING (topic_id) + LEFT JOIN tags_relations ON (tags_relations.range_id = discussions.discussion_id AND range_type = 'forum') WHERE topics.range_id = :range_id", ['range_id' => $range_id] ]; - if ($last_visit) { + if (isset($filter['last_visit'])) { $query[0] .= " AND postings.mkdate > :last_visit"; - $query[1]["last_visit"] = $last_visit; + $query[1]["last_visit"] = $filter['last_visit']; + } + + if (isset($filter['keyword'])) { + $keyword = $filter['keyword']; + $query[0] .= " AND (discussions.title LIKE :keyword OR postings.content LIKE :keyword)"; + $query[1]["keyword"] = "%$keyword%"; + } + + if (isset($filter['begin'])) { + $query[0] .= " AND postings.mkdate >= :begin"; + $query[1]['begin'] = $filter['begin']; + } + + if (isset($filter['end'])) { + $query[0] .= " AND postings.mkdate <= :end"; + $query[1]['end'] = $filter['end']; + } + + if (isset($filter['topic_ids'])) { + $query[0] .= " AND discussions.topic_id IN (:topic_ids)"; + $query[1]['topic_ids'] = $filter['topic_ids']; + } + + if (isset($filter['type_ids'])) { + $query[0] .= " AND discussions.type_id IN (:type_ids)"; + $query[1]['type_ids'] = $filter['type_ids']; + } + + if (isset($filter['tag_ids'])) { + $query[0] .= " AND tags_relations.tag_id IN (:tag_ids)"; + $query[1]['tag_ids'] = $filter['tag_ids']; + } + + if (isset($filter['user_ids'])) { + $query[0] .= " AND postings.user_id IN (:user_ids)"; + $query[1]['user_ids'] = $filter['user_ids']; + } + + if (isset($filter['status'])) { + $query[0] .= match ($filter['status']) { + 2 => " AND discussions.closed_at IS NULL", // opens + 3 => " AND discussions.closed_at IS NOT NULL", // closed + default => "" + }; } return \DBManager::get()->fetchAll( |
