Welcome to mirror list, hosted at ThFree Co, Russian Federation.

group_projects_finder.rb « finders « app - gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 8362e782ad175df235d6b4a5cee21cd0bf09d089 (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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
# frozen_string_literal: true

# GroupProjectsFinder
#
# Used to filter Projects  by set of params
#
# Arguments:
#   current_user - which user use
#   project_ids_relation: int[] - project ids to use
#   group
#   options:
#     only_owned: boolean
#     only_shared: boolean
#     limit: integer
#     include_subgroups: boolean
#   params:
#     sort: string
#     visibility_level: int
#     tags: string[]
#     personal: boolean
#     search: string
#     non_archived: boolean
#     with_issues_enabled: boolean
#     with_merge_requests_enabled: boolean
#     min_access_level: int
#
class GroupProjectsFinder < ProjectsFinder
  DEFAULT_PROJECTS_LIMIT = 100

  attr_reader :group, :options

  def initialize(group:, params: {}, options: {}, current_user: nil, project_ids_relation: nil)
    super(
      params: params,
      current_user: current_user,
      project_ids_relation: project_ids_relation
    )
    @group = group
    @options = options
  end

  def execute
    collection = super
    limit(collection)
  end

  private

  def filter_projects(collection)
    projects = super
    projects = by_feature_availability(projects)
    projects
  end

  def limit(collection)
    limit = options[:limit]

    limit.present? ? collection.with_limit(limit) : collection
  end

  def init_collection
    projects =
      if only_shared?
        [shared_projects]
      elsif only_owned?
        [owned_projects]
      else
        [owned_projects, shared_projects]
      end

    projects.map! do |project_relation|
      filter_by_visibility(project_relation)
    end

    union(projects)
  end

  def by_feature_availability(projects)
    projects = projects.with_issues_available_for_user(current_user) if params[:with_issues_enabled].present?
    projects = projects.with_merge_requests_available_for_user(current_user) if params[:with_merge_requests_enabled].present?
    projects
  end

  def filter_by_visibility(relation)
    if current_user
      if min_access_level?
        relation.visible_to_user_and_access_level(current_user, params[:min_access_level])
      else
        relation.public_or_visible_to_user(current_user)
      end
    else
      relation.public_only
    end
  end

  def union(items)
    if items.one?
      items.first
    else
      find_union(items, Project)
    end
  end

  def only_owned?
    options.fetch(:only_owned, false)
  end

  def only_shared?
    options.fetch(:only_shared, false)
  end

  # subgroups are supported only for owned projects not for shared
  def include_subgroups?
    options.fetch(:include_subgroups, false)
  end

  def owned_projects
    if include_subgroups?
      Project.for_group_and_its_subgroups(group)
    else
      group.projects
    end
  end

  def shared_projects
    group.shared_projects
  end
end

GroupProjectsFinder.prepend_if_ee('EE::GroupProjectsFinder')