This repository has been archived by the owner on Mar 27, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 21
/
page_searcher.rb
135 lines (120 loc) · 3.92 KB
/
page_searcher.rb
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
# frozen_string_literal: true
class Search::PageSearcher
def initialize(params)
@queries = params
@collection = Page.all
end
def search
[*@queries].each do |search_type, query|
if !validate_query(query)
next
else
case search_type.to_s
when 'content_search'
search_by_text(query)
when 'tags'
search_by_tags(query)
when 'language'
search_by_language(query)
when 'layout'
search_by_layout(query)
when 'campaign'
search_by_campaign(query)
when 'plugin_type'
search_by_plugin_type(query)
when 'publish_status'
search_by_publish_status(query)
when 'order_by'
order_by(query)
end
end
end
@collection | []
end
private
def validate_query(query)
# if query is an empty array, nil or an empty string, skip filtering for that query
[[], nil, ''].include? query ? false : true
end
def combine_collections(collection1, collection2)
# get union of unique values in collection1 and collection2
arr = (collection1 | collection2).uniq
# map from array back to AR collection
array_to_relation(Page, arr)
end
def array_to_relation(model, arr)
model.where(id: arr.map(&:id))
end
def search_by_title(query)
@collection = Search.full_text_search(@collection, 'title', query)
end
def search_by_text(query)
matches_by_content = Search.full_text_search(@collection, 'content', query)
@collection = combine_collections(search_by_title(query), matches_by_content)
end
def search_by_tags(tags)
matches_by_tags = []
@collection.each do |page|
# if the page has tags and if the queried tags are a subset of the page's tags
if page.tags.any? && (tags.map(&:to_i) - page.tags.pluck('id')).empty?
matches_by_tags.push(page)
end
end
@collection = array_to_relation(Page, matches_by_tags)
end
def search_by_language(query)
@collection = @collection.where(language_id: query)
end
def search_by_campaign(query)
@collection = @collection.where(campaign_id: query)
end
def search_by_layout(query)
@collection = @collection.where(liquid_layout: query)
end
def search_by_plugin_type(query)
matches_by_plugins = []
filtered_pages = @collection.pluck(:id)
query.each do |plugin_type|
begin
plugin_class = plugin_type.constantize
# Rescue for invalid plugin name - constantize throws name error if a constant with the name hasn't been initialized.
rescue
next
end
plugin_class.page.each do |page_plugin|
# If the page hasn't determined to be filtered from the collection yet
next unless filtered_pages.include?(page_plugin.page_id)
# If the plugin is active, add its page to matches
if page_plugin.active?
matches_by_plugins.push(page_plugin.page_id)
else
# If an inactive plugin is discovered, the page cannot be a match. Remove from filtered pages and matching pages.
filtered_pages.delete(page_plugin.page_id)
matches_by_plugins.delete(page_plugin.page_id)
end
end
end
# get pages that match ids of pages that contain the plugin type from the collection
@collection = @collection.where(id: matches_by_plugins)
end
def search_by_publish_status(query)
@collection = @collection.where(publish_status: query)
end
def order_by(query)
if validate_order_by(query)
@collection = if query.is_a? Array
@collection.order("#{query[0]} #{query[1]}")
else
@collection.order(query)
end
end
end
def validate_order_by(query)
acceptable = [:created_at, :updated_at, :title, :featured, :active]
if query.is_a? Array
acceptable.include? query[0].to_sym
else
acceptable.include? query.to_sym
end
end
end