Read about our upcoming Code of Conduct on this issue

project_search_results.rb 3.93 KB
Newer Older
1
2
# frozen_string_literal: true

3
4
5
6
module Gitlab
  class ProjectSearchResults < SearchResults
    attr_reader :project, :repository_ref

Jarka Kadlecová's avatar
Jarka Kadlecová committed
7
    def initialize(current_user, project, query, repository_ref = nil, per_page: 20)
8
      @current_user = current_user
9
      @project = project
10
      @repository_ref = repository_ref.presence
11
      @query = query
Jarka Kadlecová's avatar
Jarka Kadlecová committed
12
      @per_page = per_page
13
14
    end

15
    def objects(scope, page = nil)
16
17
18
19
      case scope
      when 'notes'
        notes.page(page).per(per_page)
      when 'blobs'
20
        paginated_blobs(blobs, page)
Ralf Seidler's avatar
Ralf Seidler committed
21
      when 'wiki_blobs'
22
        paginated_blobs(wiki_blobs, page)
23
24
      when 'commits'
        Kaminari.paginate_array(commits).page(page).per(per_page)
25
26
      when 'users'
        users.page(page).per(per_page)
27
      else
28
        super(scope, page, false)
29
30
31
      end
    end

32
    def users
33
      super.where(id: @project.team.members) # rubocop:disable CodeReuse/ActiveRecord
34
35
    end

36
37
38
39
    def blobs_count
      @blobs_count ||= blobs.count
    end

40
    # rubocop: disable CodeReuse/ActiveRecord
41
42
43
44
45
46
47
48
49
50
51
52
    def limited_notes_count
      return @limited_notes_count if defined?(@limited_notes_count)

      types = %w(issue merge_request commit snippet)
      @limited_notes_count = 0

      types.each do |type|
        @limited_notes_count += notes_finder(type).limit(count_limit).count
        break if @limited_notes_count >= count_limit
      end

      @limited_notes_count
53
    end
54
    # rubocop: enable CodeReuse/ActiveRecord
55

Ralf Seidler's avatar
Ralf Seidler committed
56
57
58
59
    def wiki_blobs_count
      @wiki_blobs_count ||= wiki_blobs.count
    end

60
61
62
63
    def commits_count
      @commits_count ||= commits.count
    end

64
    def single_commit_result?
65
      return false if commits_count != 1
66

67
68
69
70
      counts = %i(limited_milestones_count limited_notes_count
                  limited_merge_requests_count limited_issues_count
                  blobs_count wiki_blobs_count)
      counts.all? { |count_method| public_send(count_method).zero? } # rubocop:disable GitlabSecurity/PublicSend
71
72
    end

73
74
    private

75
76
77
78
79
80
81
82
    def paginated_blobs(blobs, page)
      results = Kaminari.paginate_array(blobs).page(page).per(per_page)

      Gitlab::Search::FoundBlob.preload_blobs(results)

      results
    end

83
    def blobs
84
85
      return [] unless Ability.allowed?(@current_user, :download_code, @project)

86
      @blobs ||= Gitlab::FileFinder.new(project, repository_project_ref).find(query)
87
88
    end

Ralf Seidler's avatar
Ralf Seidler committed
89
    def wiki_blobs
90
91
      return [] unless Ability.allowed?(@current_user, :read_wiki, @project)

Valery Sizov's avatar
Valery Sizov committed
92
93
      @wiki_blobs ||= begin
        if project.wiki_enabled? && query.present?
94
95
          unless project.wiki.empty?
            Gitlab::WikiFileFinder.new(project, repository_wiki_ref).find(query)
Valery Sizov's avatar
Valery Sizov committed
96
97
98
          else
            []
          end
99
100
101
        else
          []
        end
Ralf Seidler's avatar
Ralf Seidler committed
102
103
104
      end
    end

105
    def notes
106
107
108
      @notes ||= notes_finder(nil)
    end

109
    # rubocop: disable CodeReuse/ActiveRecord
110
111
    def notes_finder(type)
      NotesFinder.new(project, @current_user, search: query, target_type: type).execute.user.order('updated_at DESC')
112
    end
113
    # rubocop: enable CodeReuse/ActiveRecord
114

115
    def commits
116
117
118
119
120
121
122
123
      @commits ||= find_commits(query)
    end

    def find_commits(query)
      return [] unless Ability.allowed?(@current_user, :download_code, @project)

      commits = find_commits_by_message(query)
      commit_by_sha = find_commit_by_sha(query)
124
      commits |= [commit_by_sha] if commit_by_sha
125
126
127
128
129
130
131
132
133
134
      commits
    end

    def find_commits_by_message(query)
      project.repository.find_commits_by_message(query)
    end

    def find_commit_by_sha(query)
      key = query.strip
      project.repository.commit(key) if Commit.valid_hash?(key)
135
    end
136
137
138
139

    def project_ids_relation
      project
    end
140
141
142
143
144
145
146
147

    def repository_project_ref
      @repository_project_ref ||= repository_ref || project.default_branch
    end

    def repository_wiki_ref
      @repository_wiki_ref ||= repository_ref || project.wiki.default_branch
    end
148
149
150
151

    def issuable_params
      super.merge(project_id: project.id)
    end
152
153
  end
end