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
131
132
133
134
135
136
137
|
# 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
# include_ancestor_groups: 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
by_feature_availability(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
# ancestor groups are supported only for owned projects not for shared
def include_ancestor_groups?
options.fetch(:include_ancestor_groups, false)
end
def owned_projects
return group.projects unless include_subgroups? || include_ancestor_groups?
union_relations = []
union_relations << Project.for_group_and_its_subgroups(group) if include_subgroups?
union_relations << Project.for_group_and_its_ancestor_groups(group) if include_ancestor_groups?
Project.from_union(union_relations)
end
def shared_projects
group.shared_projects
end
end
GroupProjectsFinder.prepend_mod_with('GroupProjectsFinder')
|