summaryrefslogtreecommitdiff
path: root/app/controllers/forum_posts_controller.rb
blob: 2005e1e28d85be5a8153273633723d1feac0c7ba (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# frozen_string_literal: true

class ForumPostsController < ApplicationController
  skip_authorization_check only: [:index]

  def index
    setup_pagination_and_tags

    @title = 'Searching Posts'
    @per_page = ForumPost.posts_per_page
    @page_num = 1 if @page_num < 1
    @page_num = 10_000 if @page_num > 10_000

    set_content_hiding_filter ForumPost, req_permission: :undelete

    @search = search_posts
    @posts = @search.records

    respond_to do |format|
      format.html { render }
      format.json { render json: @posts.map(&:as_json) }
    end
  end

  private

  def search_posts
    options = {
      per_page:          @per_page,
      page:              @page_num,
      include_deleted:   @include_deleted,
      access_options:    { is_mod: can?(:manage, ForumPost) },
      include_destroyed: can?(:manage, ForumPost)
    }

    ForumPost.fancy_search(options) do |s|
      # Queries are used to enhance relevance sorting.

      if params[:author].present?
        if params[:author].include?('*')
          s.add_query(wildcard: { author: params[:author].downcase })
        else
          s.add_query(term: { author: params[:author].downcase })
        end

        s.add_filter(term: { anonymous: false }) if cannot?(:manage, ForumPost)
      end

      s.add_query(match: { body: { query: params[:body], operator: 'and' } }) if params[:body].present?
      s.add_query(match: { subject: { query: params[:subject], operator: 'and' } }) if params[:subject].present?
      s.add_filter(term: { topic_position: 0 }) if params[:topics_only].present?

      # The below access_level filter prevents us from seeing things we shouldn't
      s.add_filter(term: { forum_id: params[:forum_id] }) if params[:forum_id].present?
      s.add_filter(terms: { access_level: Forum.access_level_for(current_user&.role) })

      # Mod+ stuff
      if can?(:manage, ForumPost)
        s.add_filter(term: { ip: params[:ip] }) if params[:ip].present? && (IPAddr.new(params[:ip]) rescue nil)
      end

      sort_fields = { relevance: :_score }
      sort_fields.default = :created_at

      sort_dirs = { asc: :asc }
      sort_dirs.default = :desc

      s.add_sort sort_fields[params[:sort_by]] => sort_dirs[params[:sort_dir]]
    end
  end
end